home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1990-07-19 | 2.8 MB | 89,910 lines | [ TEXT/MPS ]
Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
æKY CopyrightNotice æC Copyright Apple Computer, Inc. 1985-1990, All rights reserved. 411 - CIncludes Help - QR 1 Release. Friday, July 6, 1990 1:22:42 PM æKY Help CIncludesHelp æKL AboutCIncludesHelp.h ADSP.h Aliases.h AppleEvents.h Appletalk.h Balloons.h Controls.h CursorCtl.h DatabaseAccess.h DDEV.h Desk.h Deskbus.h Devices.h Dialogs.h DisAsmLookup.h DiskInit.h Disks.h Editions.h EPPC.h ErrMgr.h Errors.h Events.h Files.h FixMath.h Folders.h Fonts.h Globals Graf3D.h HyperXCmd.h Lists.h Math.h Memory.h Menus.h Notification.h OSEvents.h OSUtils.h Packages.h Palettes.h Perf.h Picker.h Power.h PPCToolBox.h PrintTraps.h Processes.h QDOffscreen.h Quickdraw.h Resources.h Retrace.h ROMDefs.h SANE.h Scrap.h Script.h SCSI.h Segload.h Serial.h ShutDown.h Slots.h Sound.h StandardFile.h Start.h Strings.h SysEqu.h TextEdit.h Timer.h ToolUtils.h Types.h Video.h Windows.h StdCLib Assert.h Ctype.h Errno.h FCntl.h Float.h IOCtl.h Limits.h Locale.h Math.h SetJmp.h Signal.h StdArg.h StdDef.h StdIO.h StdLib.h String.h Time.h æKY AboutCincludesHelp.h æC Version 1.0 Beta: This version contains the InsideMacintosh Volume VI information. æKY ADSP.h æKL attnBufSize dspAttention dspCLDeny dspCLInit dspCLListen dspClose dspCLRemove dspInit dspNewCID dspOpen dspOptions DSPParamBlock DSPPBPtr dspRead dspRemove dspReset dspStatus dspWrite eAttention eClosed eFwdReset errAborted errAttention errFwdReset errOpening errRefNum errState eTearDown ocAccept ocEstablish ocPassive ocRequest sClosed sClosing sListening sOpen sOpening sPassive TPCCB TRattnParams TRCCB TRcloseParams TRinitParams TRioParams TRnewcidParams TRopenParams TRoptionParams TRstatusParams æKY errRefNum æFc ADSP.h æT #define æD /* constants result codes */ #define errRefNum -1280 /* bad connection refNum */ æC æKY errAborted æFc ADSP.h æT #define æD #define errAborted -1279 /* control call was aborted */ æC æKY errState æFc ADSP.h æT #define æD #define errState -1278 /* bad connection state for this operation */ æC æKY errOpening æFc ADSP.h æT #define æD #define errOpening -1277 /* open connection request was denied */ æC æKY errAttention æFc ADSP.h æT #define æD #define errAttention -1276 /* attention message too long */ æC æKY errFwdReset æFc ADSP.h æT #define æD #define errFwdReset -1275 /* read terminated by forward reset */ æC æKY dspInit æFc ADSP.h æT #define æD /* control codes */ #define dspInit 255 /* create a new connection end */ æC æKY dspRemove æFc ADSP.h æT #define æD #define dspRemove 254 /* remove a connection end */ æC æKY dspOpen æFc ADSP.h æT #define æD #define dspOpen 253 /* open a connection */ æC æKY dspClose æFc ADSP.h æT #define æD #define dspClose 252 /* close a connection */ æC æKY dspCLInit æFc ADSP.h æT #define æD #define dspCLInit 251 /* create a connection listener */ æC æKY dspCLRemove æFc ADSP.h æT #define æD #define dspCLRemove 250 /* remove a connection listener */ æC æKY dspCLListen æFc ADSP.h æT #define æD #define dspCLListen 249 /* post a listener request */ æC æKY dspCLDeny æFc ADSP.h æT #define æD #define dspCLDeny 248 /* deny an open connection request */ æC æKY dspStatus æFc ADSP.h æT #define æD #define dspStatus 247 /* get status of connection end */ æC æKY dspRead æFc ADSP.h æT #define æD #define dspRead 246 /* read data from the connection */ æC æKY dspWrite æFc ADSP.h æT #define æD #define dspWrite 245 /* write data on the connection */ æC æKY dspAttention æFc ADSP.h æT #define æD #define dspAttention 244 /* send an attention message */ æC æKY dspOptions æFc ADSP.h æT #define æD #define dspOptions 243 /* set connection end options */ æC æKY dspReset æFc ADSP.h æT #define æD #define dspReset 242 /* forward reset the connection */ æC æKY dspNewCID æFc ADSP.h æT #define æD #define dspNewCID 241 /* generate a cid for a connection end */ æC æKY ocRequest æFc ADSP.h æT #define æD /* connection opening modes */ #define ocRequest 1 /* request a connection with remote */ æC æKY ocPassive æFc ADSP.h æT #define æD #define ocPassive 2 /* wait for a connection request from remote */ æC æKY ocAccept æFc ADSP.h æT #define æD #define ocAccept 3 /* accept request as delivered by listener */ æC æKY ocEstablish æFc ADSP.h æT #define æD #define ocEstablish 4 /* consider connection to be open */ æC æKY sListening æFc ADSP.h æT #define æD /* connection end states */ #define sListening 1 /* for connection listeners */ æC æKY sPassive æFc ADSP.h æT #define æD #define sPassive 2 /* waiting for a connection request from remote */ æC æKY sOpening æFc ADSP.h æT #define æD #define sOpening 3 /* requesting a connection with remote */ æC æKY sOpen æFc ADSP.h æT #define æD #define sOpen 4 /* connection is open */ æC æKY sClosing æFc ADSP.h æT #define æD #define sClosing 5 /* connection is being torn down */ æC æKY sClosed æFc ADSP.h æT #define æD #define sClosed 6 /* connection end state is closed */ æC æKY eClosed æFc ADSP.h æT #define æD /* client event flags */ #define eClosed 0x80 /* received connection closed advice */ æC æKY eTearDown æFc ADSP.h æT #define æD #define eTearDown 0x40 /* connection closed due to broken connection */ æC æKY eAttention æFc ADSP.h æT #define æD #define eAttention 0x20 /* received attention message */ æC æKY eFwdReset æFc ADSP.h æT #define æD #define eFwdReset 0x10 /* received forward reset advice */ æC æKY attnBufSize æFc ADSP.h æT #define æD /* miscellaneous constants */ #define attnBufSize 570 /* size of client attention buffer */ æC æKY TRCCB TPCCB æFc ADSP.h æT struct æD struct TRCCB { unsigned char *ccbLink; /* link to next ccb */ unsigned short refNum; /* user reference number */ unsigned short state; /* state of the connection end */ unsigned char userFlags; /* flags for unsolicited connection events */ unsigned char localSocket; /* socket number of this connection end */ AddrBlock remoteAddress; /* internet address of remote end */ unsigned short attnCode; /* attention code received */ unsigned short attnSize; /* size of received attention data */ unsigned char *attnPtr; /* ptr to received attention data */ unsigned char reserved[220]; /* for adsp internal use */ }; typedef struct TRCCB TRCCB; typedef TRCCB *TPCCB; æC æKY TRinitParams æFc ADSP.h æT struct æD struct TRinitParams { TPCCB ccbPtr; /* pointer to connection control block */ ProcPtr userRoutine; /* client routine to call on event */ unsigned short sendQSize; /* size of send queue (0..64K bytes) */ unsigned char *sendQueue; /* client passed send queue buffer */ unsigned short recvQSize; /* size of receive queue (0..64K bytes) */ unsigned char *recvQueue; /* client passed receive queue buffer */ unsigned char *attnPtr; /* client passed receive attention buffer */ unsigned char localSocket; /* local socket number */ }; typedef struct TRinitParams TRinitParams; /* init connection end parameters */ æC æKY TRopenParams æFc ADSP.h æT struct æD struct TRopenParams { unsigned short localCID; /* local connection id */ unsigned short remoteCID; /* remote connection id */ AddrBlock remoteAddress; /* address of remote end */ AddrBlock filterAddress; /* address filter */ unsigned long sendSeq; /* local send sequence number */ unsigned short sendWindow; /* send window size */ unsigned long recvSeq; /* receive sequence number */ unsigned long attnSendSeq; /* attention send sequence number */ unsigned long attnRecvSeq; /* attention receive sequence number */ unsigned char ocMode; /* open connection mode */ unsigned char ocInterval; /* open connection request retry interval */ unsigned char ocMaximum; /* open connection request retry maximum */ }; typedef struct TRopenParams TRopenParams; /* open connection parameters */ æC æKY TRcloseParams æFc ADSP.h æT struct æD struct TRcloseParams { unsigned char abort; /* abort connection immediately if non-zero */ }; typedef struct TRcloseParams TRcloseParams; /* close connection parameters */ æC æKY TRstatusParams æFc ADSP.h æT struct æD struct TRstatusParams { TPCCB ccbPtr; /* pointer to ccb */ unsigned short sendQPending; /* pending bytes in send queue */ unsigned short sendQFree; /* available buffer space in send queue*/ unsigned short recvQPending; /* pending bytes in receive queue */ unsigned short recvQFree; /* available buffer space in receive queue */ }; typedef struct TRstatusParams TRstatusParams; /* client status parameter block */ æC æKY TRioParams æFc ADSP.h æT struct æD struct TRioParams { unsigned short reqCount; /* requested number of bytes */ unsigned short actCount; /* actual number of bytes */ unsigned char *dataPtr; /* pointer to data buffer */ unsigned char eom; /* indicates logical end of message */ unsigned char flush; /* send data now */ }; typedef struct TRioParams TRioParams; /* read/write parameter block */ æC æKY TRattnParams æFc ADSP.h æT struct æD struct TRattnParams { unsigned short attnCount; /* client attention code */ unsigned short attnSize; /* size of attention data */ unsigned char *attnData; /* pointer to attention data */ unsigned char attnInterval; /* retransmit timer in 10-tick intervals */ }; typedef struct TRattnParams TRattnParams; /* attention parameter block */ æC æKY TRoptionParams æFc ADSP.h æT struct æD struct TRoptionParams { unsigned short sendBlocking; /* quantum for data packets */ unsigned char sendTimer; /* send timer in 10-tick intervals */ unsigned char rtmtTimer; /* retransmit timer in 10-tick intervals */ unsigned char badSeqMax; /* threshold for sending retransmit advice */ unsigned char useCheckSum; /* use ddp packet checksum */ }; typedef struct TRoptionParams TRoptionParams; /* client send option parameter block */ æC æKY TRnewcidParams æFc ADSP.h æT struct æD struct TRnewcidParams { unsigned short newcid; /* new connection id returned */ }; typedef struct TRnewcidParams TRnewcidParams; /* new cid parameters */ æC æKY DSPParamBlock DSPPBPtr æFc ADSP.h æT struct æD union DSPParamBlock { QElem *qLink; short qType; short ioTrap; Ptr ioCmdAddr; ProcPtr ioCompletion; OSErr ioResult; char *ioNamePtr; short ioVRefNum; short ioCRefNum; /* adsp driver refnum */ short csCode; /* adsp driver control code */ long qStatus; /* adsp internal use */ short ccbRefNum; /* connection end reNum*/ union ; { TRinitParams initParams; /* dspInit, dspCLInit */ TRopenParams openParams; /* dspOpen, dspCLListen, dspCLDeny */ TRcloseParams closeParams; /* dspClose, dspRemove */ TRioParams ioParams; /* dspRead, dspWrite */ TRattnParams attnParams; /* dspAttention */ TRstatusParams statusParams; /* dspStatus */ TRoptionParams optionParams; /* dspOptions */ TRnewcidParams newCIDParams; /* dspNewCID */ }; typedef union DSPParamBlock DSPParamBlock; typedef DSPParamBlock *DSPPBPtr; /* ADSP CntrlParam ioQElement */ æC æKY Aliases.h æKL CanonifyFile GetAliasInfo MatchAlias NewAlias NewAliasMinimal NewAliasMinimalFromFullpath ResolveAlias SelectAlias UpdateAlias AliasFilterProcPtr AliasHandle AliasInfoType AliasPtr AliasRecord asiAliasName asiParentName asiServerName asiVolumeName asiZoneName CanonicalFileSpec CanonicalFileSpecList kARMmountVol kARMmultVols kARMnoUI kARMsearch kARMsearchMore kARMsearchRelFirst ModalFilterWithCallback rAliasType æKY rAliasType æFc Aliases.h æT #define æD /* Constants */ #define rAliasType 'alis' /* Aliases are stored as resources of this type */ æC æKY kARMmountVol æFc Aliases.h æT #define æD /* define alias resolution action rules mask */ #define kARMmountVol 0x00000001 /* mount the volume automatically */ æC æKY kARMnoUI æFc Aliases.h æT #define æD #define kARMnoUI 0x00000002 /* no user interface allowed during resolution */ æC æKY kARMmultVols æFc Aliases.h æT #define æD #define kARMmultVols 0x00000008 /* search on multiple volumes */ æC æKY kARMsearch æFc Aliases.h æT #define æD #define kARMsearch 0x00000100 /* search quickly */ æC æKY kARMsearchMore æFc Aliases.h æT #define æD #define kARMsearchMore 0x00000200 /* search further */ æC æKY kARMsearchRelFirst æFc Aliases.h æT #define æD #define kARMsearchRelFirst 0x00000400 /* search target on a relative path first */ æC æKY asiZoneName æFc Aliases.h æT #define æD /* define alias record information types */ #define asiZoneName -3 /* get zone name */ æC æKY asiServerName æFc Aliases.h æT #define æD #define asiServerName -2 /* get server name */ æC æKY asiVolumeName æFc Aliases.h æT #define æD #define asiVolumeName -1 /* get volume name */ æC æKY asiAliasName æFc Aliases.h æT #define æD #define asiAliasName 0 /* get aliased file/folder/volume name */ æC æKY asiParentName æFc Aliases.h æT #define æD #define asiParentName 1 /* get parent folder name */ æC æKY AliasInfoType æFc Aliases.h æT typedef æD typedef short AliasInfoType; /* alias record information type */ æC æKY AliasFilterProcPtr æFc Aliases.h æT typedef æD typedef pascal Boolean (*AliasFilterProcPtr) (CInfoPBPtr cpbPtr, /*I*/ Boolean *quitFlag, /*O*/ Ptr yourDataPtr); /*I*/ æC æKY ModalFilterWithCallback æFc Aliases.h æT typedef æD typedef pascal Boolean (*ModalFilterWithCallback) (DialogPtr theDialog, /*I*/ EventRecord *theEvent, /*I*/ short *itemHit, /*O*/ Ptr yourDataPtr); /*I*/ æC æKY CanonicalFileSpec CanonicalFileSpecList æFc Aliases.h æT struct æD struct CanonicalFileSpec { Short vRefNum; /* volume reference number */ long dirID; /* directory ID */ Str63 fileName; /* file name */ }; typedef struct CanonicalFileSpec CanonicalFileSpec; typedef CanonicalFileSpec *CanonicalFileSpecList; æC æKY AliasRecord AliasPtr AliasHandle æFc Aliases.h æT struct æD struct AliasRecord { OSType userType; /* appl stored type like creator type */ unsigned short aliasSize; /* alias record size in bytes, for appl usage*/ }; typedef struct AliasRecord AliasRecord; typedef AliasRecord *AliasPtr, **AliasHandle; /* define the alias record that will be the blackbox for the caller */ æC æKY CanonifyFile æFc Aliases.h æT Function æTN A823 æD pascal OSErr CanonifyFile(short vRefNum,long dirID,const Str255 fileName, CanonicalFileSpec *canonicalFile) = {0x7001,0xA823}; æDT OSErr myVariable = CanonifyFile((short) vRefNum,(long) dirID,(const Str255) fileName,( CanonicalFileSpec) * canonicalFile); æC æKY NewAlias æFc Aliases.h æT Function æTN A823 æD pascal OSErr NewAlias(const CanonicalFileSpec *fromFile,const CanonicalFileSpec *target, AliasHandle *alias) = {0x7002,0xA823}; æDT OSErr myVariable = NewAlias((const CanonicalFileSpec *) fromFile,(const CanonicalFileSpec *) target,( AliasHandle) * alias); æC æKY NewAliasMinimal æFc Aliases.h æT Function æTN A823 æD pascal OSErr NewAliasMinimal(const CanonicalFileSpec *target,AliasHandle *alias) = {0x7008,0xA823}; æDT OSErr myVariable = NewAliasMinimal((const CanonicalFileSpec *) target,(AliasHandle *) alias); æC æKY NewAliasMinimalFromFullpath æFc Aliases.h æT Function æTN A823 æD pascal OSErr NewAliasMinimalFromFullpath(short fullpathLength,const unsigned char *fullpath, const Str31 zoneName,const Str31 serverName,AliasHandle *alias) = {0x7009,0xA823}; æDT OSErr myVariable = NewAliasMinimalFromFullpath((short) fullpathLength,(const unsigned char *) fullpath,( const) Str31 zoneName,(const Str31) serverName,(AliasHandle *) alias); æC æKY ResolveAlias æFc Aliases.h æT Function æTN A823 æD pascal OSErr ResolveAlias(const CanonicalFileSpec *fromFile,AliasHandle alias, CanonicalFileSpec *target,Boolean *wasChanged) = {0x7003,0xA823}; æDT OSErr myVariable = ResolveAlias((const CanonicalFileSpec *) fromFile,(AliasHandle) alias,( CanonicalFileSpec) * target,(Boolean *) wasChanged); æC æKY SelectAlias æFc Aliases.h æT Function æTN A823 æD pascal OSErr SelectAlias(const CanonicalFileSpec *fromFile,const Str31 fileTypeName, Boolean aliasFilter,AliasHandle alias,CanonicalFileSpec *target,Boolean *wasChanged, Boolean filterProc,Ptr yourDataPtr) = {0x7004,0xA823}; æDT OSErr myVariable = SelectAlias((const CanonicalFileSpec *) fromFile,(const Str31) fileTypeName,() Boolean aliasFilter,(AliasHandle) alias,(CanonicalFileSpec *) target,(Boolean *) wasChanged,() Boolean filterProc,(Ptr) yourDataPtr); æC æKY GetAliasInfo æFc Aliases.h æT Function æTN A823 æD pascal OSErr GetAliasInfo(const AliasHandle alias,AliasInfoType index,const Str63 theString) = {0x7007,0xA823}; æDT OSErr myVariable = GetAliasInfo((const AliasHandle) alias,(AliasInfoType) index,(const Str63) theString); æC æKY MatchAlias æFc Aliases.h æT Function æTN A823 æD pascal OSErr MatchAlias(const CanonicalFileSpec *fromFile,unsigned long rulesMask, const AliasHandle alias,Short *aliasCount,const CanonicalFileSpecList *aliasList, Boolean *needsUpdate,Boolean aliasFilter,Ptr yourDataPtr) = {0x7005,0xA823}; æDT OSErr myVariable = MatchAlias((const CanonicalFileSpec *) fromFile,(unsigned long) rulesMask,( const) AliasHandle alias,(Short *) aliasCount,(const CanonicalFileSpecList *) aliasList,( Boolean) * needsUpdate,(Boolean) aliasFilter,(Ptr) yourDataPtr); æC æKY UpdateAlias æFc Aliases.h æT Function æTN A823 æD pascal OSErr UpdateAlias(const CanonicalFileSpec *fromFile,const CanonicalFileSpec *target, AliasHandle alias,Boolean *wasChanged) = {0x7006,0xA823}; æDT OSErr myVariable = UpdateAlias((const CanonicalFileSpec *) fromFile,(const CanonicalFileSpec *) target,() AliasHandle alias,(Boolean *) wasChanged); æC æKY AppleEvents.h æKL AEAddEvtToTable AECoerceDesc AECountListElems AECreateAevt AECreateDispatchTable AECreateList AEDeleteIndex AEDeleteKey AEDisposeAEDesc AEDisposeAEList AEGetAddress AEGetArray AEGetDispatchTableRsrc AEGetEventClassAndID AEGetInteractLevel AEGetKeyDesc AEGetKeyPtr AEGetNthDesc AEGetNthPtr AEGetRefCon AEGetTableEntry AEInit AEInteractionAllowed AEInteractWithUser AEProcessAppleEvent AEPutArray AEPutDesc AEPutKeyDesc AEPutKeyPtr AEPutPtr AEQuit AEResetTimer AESend AESetAddressByPSN AESetAddressBySessionID AESetAddressBySignature AESetAddressByTargetID AEWhichAevt AEAddress AEAddressHndl AEAddressPtr AEArrayType AEDesc AEInteractAllowed AEKeyDesc AEList DescType EventClass EventID kAEAliasType kAEAlwaysInteract kAEBadListElement kAEBooleanType kAECanInteract kAECanSwitchLayer kAECoercionFail kAECorruptData kAEDataArray kAEDescArray kAEDescNotFound kAEDirectObjectKeyword kAEDontReconnect kAEEventNotFound kAEEventNotInTable kAEFalseType kAEHandleArray kAEHighPriority kAEInteractionWithSelf kAEInteractWithAll kAEInteractWithLocal kAEKeyDescArray kAEListType kAELongType kAENeverInteract kAENoReply kAENormalPriority kAENotAEList kAENotAppleEvent kAENoUserInteraction kAEOpenApplication kAEOpenDocuments kAEPackedArray kAEPrintDocuments kAEQueueReply kAEQuitApplication kAEReplyNotValid kAETimeoutErr kAETrueType kAEUnknownInteract kAEUnknownSendMode KAEWaitCanceled kAEWaitReply kAEWantReceipt kAEWildType kAEWrongDataType kAEWrongVersion kAutoGenerateRefcon kCoreEventClass KeyWord æKY kAELongType æFc AppleEvents.h æT #define æD #define kAELongType 'long' æC æKY kAEListType æFc AppleEvents.h æT #define æD #define kAEListType 'list' æC æKY kAEWildType æFc AppleEvents.h æT #define æD #define kAEWildType '****' æC æKY kAEBooleanType æFc AppleEvents.h æT #define æD #define kAEBooleanType 'bool' æC æKY kAETrueType æFc AppleEvents.h æT #define æD #define kAETrueType 'true' æC æKY kAEFalseType æFc AppleEvents.h æT #define æD #define kAEFalseType 'fals' æC æKY kAEAliasType æFc AppleEvents.h æT #define æD #define kAEAliasType 'alis' æC æKY kAEDirectObjectKeyword æFc AppleEvents.h æT #define æD #define kAEDirectObjectKeyword '----' æC æKY kCoreEventClass æFc AppleEvents.h æT #define æD #define kCoreEventClass 'aevt' æC æKY kAEOpenApplication æFc AppleEvents.h æT #define æD #define kAEOpenApplication 'oapp' æC æKY kAEOpenDocuments æFc AppleEvents.h æT #define æD #define kAEOpenDocuments 'odoc' æC æKY kAEPrintDocuments æFc AppleEvents.h æT #define æD #define kAEPrintDocuments 'pdoc' æC æKY kAEQuitApplication æFc AppleEvents.h æT #define æD #define kAEQuitApplication 'quit' æC æKY kAENoReply æFc AppleEvents.h æT #define æD #define kAENoReply 0x00000001 /* Sender doesn't want a reply to event */ æC æKY kAEQueueReply æFc AppleEvents.h æT #define æD #define kAEQueueReply 0x00000002 /* Sender wants a reply but won't wait */ æC æKY kAEWaitReply æFc AppleEvents.h æT #define æD #define kAEWaitReply 0x00000003 /* Sender wants a reply and will be waiting */ æC æKY kAENeverInteract æFc AppleEvents.h æT #define æD #define kAENeverInteract 0x00000010 /* Server should not interact with user */ æC æKY kAECanInteract æFc AppleEvents.h æT #define æD #define kAECanInteract 0x00000020 /* Server may try to interact with user */ æC æKY kAEAlwaysInteract æFc AppleEvents.h æT #define æD #define kAEAlwaysInteract 0x00000030 /* Server should always interact with user */ æC æKY kAECanSwitchLayer æFc AppleEvents.h æT #define æD #define kAECanSwitchLayer 0x00000040 /* Interaction may switch layer */ æC æKY kAEDontReconnect æFc AppleEvents.h æT #define æD #define kAEDontReconnect 0x00000080 /* don't reconnect if there is a sessClosedErr */ æC æKY kAEWantReceipt æFc AppleEvents.h æT #define æD #define kAEWantReceipt nReturnReceipt /* Send wants a receipt of message */ æC æKY kAENormalPriority æFc AppleEvents.h æT #define æD #define kAENormalPriority 0x00000000 /* Post message at the end of event queue */ æC æKY kAEHighPriority æFc AppleEvents.h æT #define æD #define kAEHighPriority nAttnMsg /* Post message at the front of the event queue */ æC æKY kAutoGenerateRefcon æFc AppleEvents.h æT #define æD #define kAutoGenerateRefcon 0 æC æKY kAEEventNotInTable æFc AppleEvents.h æT #define æD #define kAEEventNotInTable 0 /* Passed to the general dispatch proc if the event received was not in the dispatch table */ æC æKY kAECoercionFail æFc AppleEvents.h æT #define æD /* Error messages in response to reading and writing buffer contents */ #define kAECoercionFail -1700 æC æKY kAEDescNotFound æFc AppleEvents.h æT #define æD #define kAEDescNotFound -1701 æC æKY kAECorruptData æFc AppleEvents.h æT #define æD #define kAECorruptData -1702 æC æKY kAEWrongDataType æFc AppleEvents.h æT #define æD #define kAEWrongDataType -1703 æC æKY kAENotAEList æFc AppleEvents.h æT #define æD #define kAENotAEList -1704 æC æKY kAEBadListElement æFc AppleEvents.h æT #define æD #define kAEBadListElement -1705 æC æKY kAEWrongVersion æFc AppleEvents.h æT #define æD #define kAEWrongVersion -1706 æC æKY kAENotAppleEvent æFc AppleEvents.h æT #define æD #define kAENotAppleEvent -1707 æC æKY kAEEventNotFound æFc AppleEvents.h æT #define æD /* Error messages in response to sending/receiving a message */ #define kAEEventNotFound -1708 /* The event isn't in the supplied event table */ æC æKY kAEReplyNotValid æFc AppleEvents.h æT #define æD #define kAEReplyNotValid -1709 /* AEResetTimer was passed an invalid reply */ æC æKY kAEUnknownSendMode æFc AppleEvents.h æT #define æD #define kAEUnknownSendMode -1710 /* Mode wasn't NoReply, WaitReply, QueueReply; or Interaction level is unknown */ æC æKY KAEWaitCanceled æFc AppleEvents.h æT #define æD #define KAEWaitCanceled -1711 /* User cancelled out of wait loop for reply or receipt */ æC æKY kAETimeoutErr æFc AppleEvents.h æT #define æD #define kAETimeoutErr -1712 /* AppleEvent time out */ æC æKY kAENoUserInteraction æFc AppleEvents.h æT #define æD #define kAENoUserInteraction -1713 /* no user interaction allowed */ æC æKY AEArrayType kAEDataArray kAEPackedArray kAEHandleArray kAEDescArray kAEKeyDescArray æFc AppleEvents.h æT enum æD enum {kAEDataArray,kAEPackedArray,kAEHandleArray,kAEDescArray,kAEKeyDescArray}; typedef unsigned char AEArrayType; æC æKY AEInteractAllowed kAEUnknownInteract kAEInteractionWithSelf kAEInteractWithLocal kAEInteractWithAll æFc AppleEvents.h æT enum æD enum {kAEUnknownInteract,kAEInteractionWithSelf,kAEInteractWithLocal,kAEInteractWithAll}; typedef unsigned char AEInteractAllowed; æC æKY AEList æFc AppleEvents.h æT typedef æD typedef long AEList; æC æKY KeyWord æFc AppleEvents.h æT typedef æD typedef unsigned long KeyWord; æC æKY EventClass æFc AppleEvents.h æT typedef æD typedef unsigned long EventClass; æC æKY EventID æFc AppleEvents.h æT typedef æD typedef unsigned long EventID; æC æKY DescType æFc AppleEvents.h æT typedef æD typedef OSType DescType; æC æKY AEAddress AEAddressPtr AEAddressHndl æFc AppleEvents.h æT struct æD union AEAddress { ProcessSerialNumber receiverIDasPSN; OSType receiverIDasSig; long receiverIDasSess; TargetID receiverIDasTargetID; }; typedef union AEAddress AEAddress; typedef AEAddress *AEAddressPtr, **AEAddressHndl; æC æKY AEDesc æFc AppleEvents.h æT struct æD struct AEDesc { DescType descriptorType; union{ Handle asDataHdl; AEList asAEList; }Boolean; }; typedef struct AEDesc AEDesc; æC æKY AEKeyDesc æFc AppleEvents.h æT struct æD struct AEKeyDesc { KeyWord descKey; AEDesc descContent; }; typedef struct AEKeyDesc AEKeyDesc; æC æKY AEInit æFc AppleEvents.h æT Function æD pascal OSErr AEInit(ProcPtr dispatchProc,ProcPtr coercionProc,ProcPtr nonAevtHandler); æDT OSErr myVariable = AEInit((ProcPtr) dispatchProc,(ProcPtr) coercionProc,(ProcPtr) nonAevtHandler); æC æKY AEQuit æFc AppleEvents.h æT Function æD pascal void AEQuit(void); æDT AEQuit()(void); æC æKY AEPutPtr æFc AppleEvents.h æT Function æD pascal OSErr AEPutPtr(AEList theList,long index,DescType typeCode,Ptr dataPtr, long dataSize); æDT OSErr myVariable = AEPutPtr((AEList) theList,(long) index,(DescType) typeCode,(Ptr) dataPtr,() long dataSize); æC æKY AEPutDesc æFc AppleEvents.h æT Function æD pascal OSErr AEPutDesc(AEList theList,long index,const AEDesc *theDesc); æDT OSErr myVariable = AEPutDesc((AEList) theList,(long) index,(const AEDesc *) theDesc); æC æKY AEPutKeyPtr æFc AppleEvents.h æT Function æD pascal OSErr AEPutKeyPtr(AEList theList,KeyWord key,DescType typeCode,Ptr dataPtr, long dataSize); æDT OSErr myVariable = AEPutKeyPtr((AEList) theList,(KeyWord) key,(DescType) typeCode,(Ptr) dataPtr,() long dataSize); æC æKY AEPutKeyDesc æFc AppleEvents.h æT Function æD pascal OSErr AEPutKeyDesc(AEList theList,KeyWord key,const AEDesc *theDesc); æDT OSErr myVariable = AEPutKeyDesc((AEList) theList,(KeyWord) key,(const AEDesc *) theDesc); æC æKY AEGetNthPtr æFc AppleEvents.h æT Function æD pascal OSErr AEGetNthPtr(AEList theList,long index,DescType desiredType, KeyWord *key,DescType *typeCode,Ptr dataPtr,long maxSize,long *actualSize); æDT OSErr myVariable = AEGetNthPtr((AEList) theList,(long) index,(DescType) desiredType,( KeyWord) * key,(DescType *) typeCode,(Ptr) dataPtr,(long) maxSize,(long *) actualSize); æC æKY AEGetNthDesc æFc AppleEvents.h æT Function æD pascal OSErr AEGetNthDesc(AEList theList,long index,DescType desiredType, KeyWord *key,AEDesc *theDesc); æDT OSErr myVariable = AEGetNthDesc((AEList) theList,(long) index,(DescType) desiredType,( KeyWord) * key,(AEDesc *) theDesc); æC æKY AEGetKeyPtr æFc AppleEvents.h æT Function æD pascal OSErr AEGetKeyPtr(AEList theList,KeyWord key,DescType desiredType, DescType *typeCode,Ptr dataPtr,long maxSize,long *actualSize); æDT OSErr myVariable = AEGetKeyPtr((AEList) theList,(KeyWord) key,(DescType) desiredType,( DescType) * typeCode,(Ptr) dataPtr,(long) maxSize,(long *) actualSize); æC æKY AEGetKeyDesc æFc AppleEvents.h æT Function æD pascal OSErr AEGetKeyDesc(AEList theList,KeyWord key,DescType desiredType, AEDesc *theDesc); æDT OSErr myVariable = AEGetKeyDesc((AEList) theList,(KeyWord) key,(DescType) desiredType,( AEDesc) * theDesc); æC æKY AEGetArray æFc AppleEvents.h æT Function æD pascal OSErr AEGetArray(AEList theList,AEArrayType arrayType,Ptr arrayPtr, long bufSize,DescType *elemType,long *elemSize,long *itemCount); æDT OSErr myVariable = AEGetArray((AEList) theList,(AEArrayType) arrayType,(Ptr) arrayPtr,() long bufSize,(DescType *) elemType,(long *) elemSize,(long *) itemCount); æC æKY AEPutArray æFc AppleEvents.h æT Function æD pascal OSErr AEPutArray(AEList theList,AEArrayType arrayType,Ptr arrayPtr, DescType elemType,long elemSize,long itemCount); æDT OSErr myVariable = AEPutArray((AEList) theList,(AEArrayType) arrayType,(Ptr) arrayPtr,() DescType elemType,(long) elemSize,(long) itemCount); æC æKY AEDeleteIndex æFc AppleEvents.h æT Function æD pascal OSErr AEDeleteIndex(AEList theList,long index); æDT OSErr myVariable = AEDeleteIndex((AEList) theList,(long) index); æC æKY AEDeleteKey æFc AppleEvents.h æT Function æD pascal OSErr AEDeleteKey(AEList theList,KeyWord key); æDT OSErr myVariable = AEDeleteKey((AEList) theList,(KeyWord) key); æC æKY AECoerceDesc æFc AppleEvents.h æT Function æD pascal OSErr AECoerceDesc(const AEDesc *desc,DescType toType,AEDesc *result); æDT OSErr myVariable = AECoerceDesc((const AEDesc *) desc,(DescType) toType,(AEDesc *) result); æC æKY AEDisposeAEList æFc AppleEvents.h æT Function æD pascal void AEDisposeAEList(AEList theArg); æDT AEDisposeAEList((AEList) theArg); æC æKY AEDisposeAEDesc æFc AppleEvents.h æT Function æD pascal void AEDisposeAEDesc(const AEDesc *theArg); æDT AEDisposeAEDesc((const AEDesc *) theArg); æC æKY AECreateAevt æFc AppleEvents.h æT Function æD pascal OSErr AECreateAevt(EventClass theEventClass,EventID theEventID,AEAdress target, long theRefCon,AEList *result); æDT OSErr myVariable = AECreateAevt((EventClass) theEventClass,(EventID) theEventID,(AEAdress) target,() long theRefCon,(AEList *) result); æC æKY AEGetEventClassAndID æFc AppleEvents.h æT Function æD /* Extract the event class and id from the specified message */ pascal void AEGetEventClassAndID(AEList theAevt,EventClass *theEventClass, EventID *theEventID); æDT /* Extract the event class and id from the specified message */ pascal void myVariable = AEGetEventClassAndID((AEList) theAevt,(EventClass *) theEventClass,( EventID) * theEventID); æC æKY AEGetRefCon æFc AppleEvents.h æT Function æD /* Extract the event class and id from the specified message */ pascal void AEGetRefCon(AEList theAevt,long *refCon); æDT /* Extract the event class and id from the specified message */ pascal void myVariable = AEGetRefCon((AEList) theAevt,(long *) refCon); æC æKY AEGetAddress æFc AppleEvents.h æT Function æD /* Extract the address from the specified message */ pascal void AEGetAddress(AEList theAevt,AEAddress *address); æDT /* Extract the address from the specified message */ pascal void myVariable = AEGetAddress((AEList) theAevt,(AEAddress *) address); æC æKY AECreateList æFc AppleEvents.h æT Function æD pascal OSErr AECreateList(Ptr factoringPtr,long factoredSize,Boolean isRecord, AEDesc *resultList); æDT OSErr myVariable = AECreateList((Ptr) factoringPtr,(long) factoredSize,(Boolean) isRecord,( AEDesc) * resultList); æC æKY AECountListElems æFc AppleEvents.h æT Function æD pascal long AECountListElems(AEList theList); æDT long myVariable = AECountListElems((AEList) theList); æC æKY AESend æFc AppleEvents.h æT Function æD pascal OSErr AESend(AEList theList,AEList *theReply,long sendMode,INTEGER sendPriority, long timeOut,ProcPtr idleProc); æDT OSErr myVariable = AESend((AEList) theList,(AEList *) theReply,(long) sendMode,(INTEGER) sendPriority,() long timeOut,(ProcPtr) idleProc); æC æKY AEResetTimer æFc AppleEvents.h æT Function æD /* Convience routine. Create and send a 'wait' message from the information in the reply. */ pascal OSErr AEResetTimer(AEList reply); æDT /* Convience routine. Create and send a 'wait' message from the information in the reply. */ pascal OSErr myVariable = AEResetTimer((AEList) reply); æC æKY AESetAddressByPSN æFc AppleEvents.h æT Function æD /* Fill theAddressObject as receiverIDisPSN */ pascal void AESetAddressByPSN(const ProcessSerialNumber *thePSN,AEAdress *theAddress); æDT /* Fill theAddressObject as receiverIDisPSN */ pascal void myVariable = AESetAddressByPSN((const ProcessSerialNumber *) thePSN,(AEAdress *) theAddress); æC æKY AESetAddressBySignature æFc AppleEvents.h æT Function æD /* Fill theAddressObject as receiverIDisSignature */ pascal void AESetAddressBySignature(OSType theSig,AEAddress *theAddress); æDT /* Fill theAddressObject as receiverIDisSignature */ pascal void myVariable = AESetAddressBySignature((OSType) theSig,(AEAddress *) theAddress); æC æKY AESetAddressBySessionID æFc AppleEvents.h æT Function æD /* Fill theAddressObject as receiverIDisSessionID */ pascal void AESetAddressBySessionID(long theSessionID,AEAddress *theAddress); æDT /* Fill theAddressObject as receiverIDisSessionID */ pascal void myVariable = AESetAddressBySessionID((long) theSessionID,(AEAddress *) theAddress); æC æKY AESetAddressByTargetID æFc AppleEvents.h æT Function æD /* Fill theAddressObject as receiverIDisTargetID */ pascal void AESetAddressByTargetID(const TargetID *theTargetID,AEAddress *theAddress); æDT /* Fill theAddressObject as receiverIDisTargetID */ pascal void myVariable = AESetAddressByTargetID((const TargetID *) theTargetID,(AEAddress *) theAddress); æC æKY AEProcessAppleEvent æFc AppleEvents.h æT Function æD pascal OSErr AEProcessAppleEvent(const EventRecord *eventRec); æDT OSErr myVariable = AEProcessAppleEvent((const EventRecord *) eventRec); æC æKY AEGetDispatchTableRsrc æFc AppleEvents.h æT Function æD /* Load an event table from a 'AEDF' resource. This of course will only be of use to applications using a general dispatch routine rather than doing a direct dispatch to a handler. */ pascal OSErr AEGetDispatchTableRsrc(INTEGER tableID); æDT /* Load an event table from a 'AEDF' resource. This of course will only be of use to applications using a general dispatch routine rather than doing a direct dispatch to a handler. */ pascal OSErr myVariable = AEGetDispatchTableRsrc((INTEGER) tableID); æC æKY AECreateDispatchTable æFc AppleEvents.h æT Function æD /* Create an event table with one memory manager call for the number of events specified. If more events are added to the table with AESetupEventTable, the table will be grown automatically. */ pascal OSErr AECreateDispatchTable(INTEGER numEntries); æDT /* Create an event table with one memory manager call for the number of events specified. If more events are added to the table with AESetupEventTable, the table will be grown automatically. */ pascal OSErr myVariable = AECreateDispatchTable((INTEGER) numEntries); æC æKY AEAddEvtToTable æFc AppleEvents.h æT Function æD /* Add a single event to the table, expanding if necessary. */ pascal OSErr AEAddEvtToTable(EventClass theEventClass,EventID theEventID, long value); æDT /* Add a single event to the table, expanding if necessary. */ pascal OSErr myVariable = AEAddEvtToTable((EventClass) theEventClass,(EventID) theEventID,() long value); æC æKY AEGetTableEntry æFc AppleEvents.h æT Function æD /* returns the value of the specified event in theValue. kAEEventNotFound if not found. */ pascal OSErr AEGetTableEntry(EventClass theEventClass,EventID theEventID, long *theValue); æDT /* returns the value of the specified event in theValue. kAEEventNotFound if not found. */ pascal OSErr myVariable = AEGetTableEntry((EventClass) theEventClass,(EventID) theEventID,( long) * theValue); æC æKY AEInteractWithUser æFc AppleEvents.h æT Function æD pascal OSErr AEInteractWithUser(long timeOut,QElemPtr nmReqPtr); æDT OSErr myVariable = AEInteractWithUser((long) timeOut,(QElemPtr) nmReqPtr); æC æKY AEGetInteractLevel æFc AppleEvents.h æT Function æD /* returns kAENeverInteract, kAECanInteract or kAEAlwaysInteract */ pascal INTEGER AEGetInteractLevel(AEList theAevt); æDT /* returns kAENeverInteract, kAECanInteract or kAEAlwaysInteract */ pascal INTEGER myVariable = AEGetInteractLevel((AEList) theAevt); æC æKY AEInteractionAllowed æFc AppleEvents.h æT Function æD pascal AEInteractAllowed AEInteractionAllowed(AEInteractAllowed theLevel); æDT AEInteractAllowed myVariable = AEInteractionAllowed((AEInteractAllowed) theLevel); æC æKY AEWhichAevt æFc AppleEvents.h æT Function æD pascal AEList AEWhichAevt(void); æDT AEList myVariable = AEWhichAevt()(void); æC æKY AppleTalk.h æKL AFPCommand ASPAbortOS ASPCloseAll ASPCloseSession ASPGetParms ASPGetStatus ASPOpenSession ASPUserCommand ASPUserWrite ATPAddRsp ATPCloseSocket ATPGetRequest ATPLoad ATPOpenSocket ATPReqCancel ATPRequest ATPResponse ATPRspCancel ATPSndRequest ATPSndRsp ATPUnload BuildBDS BuildDDPwds BuildLAPwds DDPCloseSocket DDPOpenSocket DDPRdCancel DDPRead DDPWrite GetBridgeAddress GetLocalZones GetMyZone GetNodeAddress GetZoneList IsATPOpen IsMPPOpen LAPCloseProtocol LAPOpenProtocol LAPRdCancel LAPRead LAPWrite MPPClose MPPOpen NBPConfirm NBPExtract NBPLoad NBPLookup NBPRegister NBPRemove NBPSetEntity NBPSetNTE NBPUnload OpenXPP PAddResponse PATalkClosePrep PAttachPH PCancelATalkClosePrep PCloseATPSkt PCloseSkt PConfirmName PDetachPH PGetAppleTalkInfo PGetRequest PKillAllGetReq PKillGetReq PKillNBP PKillSendReq PLookupName PNSendRequest POpenATPSkt POpenSkt PRegisterName PRelRspCB PRelTCB PRemoveName PSendRequest PSendResponse PSetSelfSend PWriteDDP PWriteLAP RemoveHdlBlocks . ABByte ABCallType ABProtoType AddrBlock afpAddAPPL afpAddCmt afpAddIcon afpByteRangeLock AFPCommandBlock afpContLogin afpCopyFile afpDelete afpDirClose afpDirCreate afpDTClose afpDTOpen afpEnumerate afpFileCreate afpFlush afpForkClose afpForkFlush afpGetAPPL afpGetCmt afpGetDirParms afpGetFileParms afpGetFlDrParms afpGetForkParms afpGetIcon afpGetSInfo afpGetSParms afpGetVolParms afpGtIcnInfo afpLogin AFPLoginPrm afpLogout afpMapID afpMapName afpMove afpOpenDir afpOpenFork afpOpenVol afpRead afpRename afpRmvAPPL afpRmvCmt afpSetDirParms afpSetFileParms afpSetFlDrParms afpSetForkParms afpSetVolParms afpVolClose afpWrite ASPAbortPrm ASPGetparmsBlk ASPOpenPrm ASPOpenPrmPtr ATATPRec ATATPRecHandle ATATPRecPtr ATDDPRec ATDDPRecHandle ATDDPRecPtr ATLAPRec ATLAPRecHandle ATLAPRecPtr ATNBPRec ATNBPRecHandle ATNBPRecPtr ATPaddrBlock ATPaKillQEl ATPatpFlags ATPatpSocket ATPbdsPointer ATPbdsSize ATPbitMap ATPcsCode atpEOMvalue ATPioCompletion ATPioRefNum ATPioResult ATPmisc1 ATPmisc2 ATPnumOfBuffs ATPnumOfResps ATPParamBlock ATPparms ATPPBPtr atpProto ATPreqLength ATPreqPointer ATPreqTID ATPretryCount ATPrspNum atpSendChkvalue atpSize atpSTSvalue atpTIDValidvalue ATPtimeOutVal ATPtransID ATPuserData atpXOvalue ATQEntry BDSElement BitMapType DDPchecksumFlag DDPlistener DDPparms ddpProto ddpSize DDPsocket DDPwdsPointer EntityName EntityPtr Killparms LAPAdrBlock LAPhandler LAPMgrCall LAPMgrPtr LAPparms lapProto LAPprotType lapSize LAPwdsPointer MOREATPHeader MPPATPHeader MPPcsCode MPPioCompletion MPPioRefNum MPPioResult MPPParamBlock MPPparms MPPPBPtr NamesTableEntry NBPconfirmAddr NBPcount NBPentityPtr NBPinterval NBPKillparms NBPmaxToGet NBPnewSocket NBPnKillQEl NBPntQElPtr NBPnumGotten NBPparms nbpProto NBPretBuffPtr NBPretBuffSize nbpSize NBPverifyFlag NTElement RetransType scbMemSize SendReqparms SetSelfparms Str32 tATPAddRsp tATPGetRequest tATPRequest tATPResponse tATPSdRsp tATPSndRequest tDDPRead tDDPWrite tLAPRead tLAPWrite tNBPConfirm tNBPLookup tNBPRegister WDSElement xppFlagClr xppFlagSet xppLoadedBit XPPParamBlock XPPParmBlkPtr XPPPBHeader XPPPrmBlk xppRefNum xppUnitNum æKY afpByteRangeLock æFc AppleTalk.h æT #define æD #define afpByteRangeLock 1 /*AFPCall command codes*/ æC æKY afpVolClose æFc AppleTalk.h æT #define æD #define afpVolClose 2 /*AFPCall command codes*/ æC æKY afpDirClose æFc AppleTalk.h æT #define æD #define afpDirClose 3 /*AFPCall command codes*/ æC æKY afpForkClose æFc AppleTalk.h æT #define æD #define afpForkClose 4 /*AFPCall command codes*/ æC æKY afpCopyFile æFc AppleTalk.h æT #define æD #define afpCopyFile 5 /*AFPCall command codes*/ æC æKY afpDirCreate æFc AppleTalk.h æT #define æD #define afpDirCreate 6 /*AFPCall command codes*/ æC æKY afpFileCreate æFc AppleTalk.h æT #define æD #define afpFileCreate 7 /*AFPCall command codes*/ æC æKY afpDelete æFc AppleTalk.h æT #define æD #define afpDelete 8 /*AFPCall command codes*/ æC æKY afpEnumerate æFc AppleTalk.h æT #define æD #define afpEnumerate 9 /*AFPCall command codes*/ æC æKY afpFlush æFc AppleTalk.h æT #define æD #define afpFlush 10 /*AFPCall command codes*/ æC æKY afpForkFlush æFc AppleTalk.h æT #define æD #define afpForkFlush 11 /*AFPCall command codes*/ æC æKY afpGetDirParms æFc AppleTalk.h æT #define æD #define afpGetDirParms 12 /*AFPCall command codes*/ æC æKY afpGetFileParms æFc AppleTalk.h æT #define æD #define afpGetFileParms 13 /*AFPCall command codes*/ æC æKY afpGetForkParms æFc AppleTalk.h æT #define æD #define afpGetForkParms 14 /*AFPCall command codes*/ æC æKY afpGetSInfo æFc AppleTalk.h æT #define æD #define afpGetSInfo 15 /*AFPCall command codes*/ æC æKY afpGetSParms æFc AppleTalk.h æT #define æD #define afpGetSParms 16 /*AFPCall command codes*/ æC æKY afpGetVolParms æFc AppleTalk.h æT #define æD #define afpGetVolParms 17 /*AFPCall command codes*/ æC æKY afpLogin æFc AppleTalk.h æT #define æD #define afpLogin 18 /*AFPCall command codes*/ æC æKY afpContLogin æFc AppleTalk.h æT #define æD #define afpContLogin 19 /*AFPCall command codes*/ æC æKY afpLogout æFc AppleTalk.h æT #define æD #define afpLogout 20 /*AFPCall command codes*/ æC æKY afpMapID æFc AppleTalk.h æT #define æD #define afpMapID 21 /*AFPCall command codes*/ æC æKY afpMapName æFc AppleTalk.h æT #define æD #define afpMapName 22 /*AFPCall command codes*/ æC æKY afpMove æFc AppleTalk.h æT #define æD #define afpMove 23 /*AFPCall command codes*/ æC æKY afpOpenVol æFc AppleTalk.h æT #define æD #define afpOpenVol 24 /*AFPCall command codes*/ æC æKY afpOpenDir æFc AppleTalk.h æT #define æD #define afpOpenDir 25 /*AFPCall command codes*/ æC æKY afpOpenFork æFc AppleTalk.h æT #define æD #define afpOpenFork 26 /*AFPCall command codes*/ æC æKY afpRead æFc AppleTalk.h æT #define æD #define afpRead 27 /*AFPCall command codes*/ æC æKY afpRename æFc AppleTalk.h æT #define æD #define afpRename 28 /*AFPCall command codes*/ æC æKY afpSetDirParms æFc AppleTalk.h æT #define æD #define afpSetDirParms 29 /*AFPCall command codes*/ æC æKY afpSetFileParms æFc AppleTalk.h æT #define æD #define afpSetFileParms 30 /*AFPCall command codes*/ æC æKY afpSetForkParms æFc AppleTalk.h æT #define æD #define afpSetForkParms 31 /*AFPCall command codes*/ æC æKY afpSetVolParms æFc AppleTalk.h æT #define æD #define afpSetVolParms 32 /*AFPCall command codes*/ æC æKY afpWrite æFc AppleTalk.h æT #define æD #define afpWrite 33 /*AFPCall command codes*/ æC æKY afpGetFlDrParms æFc AppleTalk.h æT #define æD #define afpGetFlDrParms 34 /*AFPCall command codes*/ æC æKY afpSetFlDrParms æFc AppleTalk.h æT #define æD #define afpSetFlDrParms 35 /*AFPCall command codes*/ æC æKY afpDTOpen æFc AppleTalk.h æT #define æD #define afpDTOpen 48 /*AFPCall command codes*/ æC æKY afpDTClose æFc AppleTalk.h æT #define æD #define afpDTClose 49 /*AFPCall command codes*/ æC æKY afpGetIcon æFc AppleTalk.h æT #define æD #define afpGetIcon 51 /*AFPCall command codes*/ æC æKY afpGtIcnInfo æFc AppleTalk.h æT #define æD #define afpGtIcnInfo 52 /*AFPCall command codes*/ æC æKY afpAddAPPL æFc AppleTalk.h æT #define æD #define afpAddAPPL 53 /*AFPCall command codes*/ æC æKY afpRmvAPPL æFc AppleTalk.h æT #define æD #define afpRmvAPPL 54 /*AFPCall command codes*/ æC æKY afpGetAPPL æFc AppleTalk.h æT #define æD #define afpGetAPPL 55 /*AFPCall command codes*/ æC æKY afpAddCmt æFc AppleTalk.h æT #define æD #define afpAddCmt 56 /*AFPCall command codes*/ æC æKY afpRmvCmt æFc AppleTalk.h æT #define æD #define afpRmvCmt 57 /*AFPCall command codes*/ æC æKY afpGetCmt æFc AppleTalk.h æT #define æD #define afpGetCmt 58 /*AFPCall command codes*/ æC æKY afpAddIcon æFc AppleTalk.h æT #define æD #define afpAddIcon 192 /*Special code for ASP Write commands*/ æC æKY xppLoadedBit æFc AppleTalk.h æT #define æD #define xppLoadedBit 5 /* XPP bit in PortBUse */ æC æKY xppUnitNum æFc AppleTalk.h æT #define æD #define xppUnitNum 40 /*Unit number for XPP (old ROMs) */ æC æKY xppRefNum æFc AppleTalk.h æT #define æD #define xppRefNum -41 /*.XPP reference number */ æC æKY scbMemSize æFc AppleTalk.h æT #define æD #define scbMemSize 192 /*Size of memory for SCB */ æC æKY xppFlagClr æFc AppleTalk.h æT #define æD #define xppFlagClr 0 /*Cs for AFPCommandBlock */ æC æKY xppFlagSet æFc AppleTalk.h æT #define æD #define xppFlagSet 128 /*StartEndFlag & NewLineFlag fields. */ æC æKY lapSize æFc AppleTalk.h æT #define æD #define lapSize 20 æC æKY ddpSize æFc AppleTalk.h æT #define æD #define ddpSize 26 æC æKY nbpSize æFc AppleTalk.h æT #define æD #define nbpSize 26 æC æKY atpSize æFc AppleTalk.h æT #define æD #define atpSize 56 æC æKY MPPioCompletion æFc AppleTalk.h æT #define æD #define MPPioCompletion MPP.ioCompletion æC æKY MPPioResult æFc AppleTalk.h æT #define æD #define MPPioResult MPP.ioResult æC æKY MPPioRefNum æFc AppleTalk.h æT #define æD #define MPPioRefNum MPP.ioRefNum æC æKY MPPcsCode æFc AppleTalk.h æT #define æD #define MPPcsCode MPP.csCode æC æKY LAPprotType æFc AppleTalk.h æT #define æD #define LAPprotType LAP.protType æC æKY LAPwdsPointer æFc AppleTalk.h æT #define æD #define LAPwdsPointer LAP.LAPptrs.wdsPointer æC æKY LAPhandler æFc AppleTalk.h æT #define æD #define LAPhandler LAP.LAPptrs.handler æC æKY DDPsocket æFc AppleTalk.h æT #define æD #define DDPsocket DDP.socket æC æKY DDPchecksumFlag æFc AppleTalk.h æT #define æD #define DDPchecksumFlag DDP.checksumFlag æC æKY DDPwdsPointer æFc AppleTalk.h æT #define æD #define DDPwdsPointer DDP.DDPptrs.wdsPointer æC æKY DDPlistener æFc AppleTalk.h æT #define æD #define DDPlistener DDP.DDPptrs.listener æC æKY NBPinterval æFc AppleTalk.h æT #define æD #define NBPinterval NBP.interval æC æKY NBPcount æFc AppleTalk.h æT #define æD #define NBPcount NBP.count æC æKY NBPntQElPtr æFc AppleTalk.h æT #define æD #define NBPntQElPtr NBP.NBPPtrs.ntQElPtr æC æKY NBPentityPtr æFc AppleTalk.h æT #define æD #define NBPentityPtr NBP.NBPPtrs.entityPtr æC æKY NBPverifyFlag æFc AppleTalk.h æT #define æD #define NBPverifyFlag NBP.parm.verifyFlag æC æKY NBPretBuffPtr æFc AppleTalk.h æT #define æD #define NBPretBuffPtr NBP.parm.Lookup.retBuffPtr æC æKY NBPretBuffSize æFc AppleTalk.h æT #define æD #define NBPretBuffSize NBP.parm.Lookup.retBuffSize æC æKY NBPmaxToGet æFc AppleTalk.h æT #define æD #define NBPmaxToGet NBP.parm.Lookup.maxToGet æC æKY NBPnumGotten æFc AppleTalk.h æT #define æD #define NBPnumGotten NBP.parm.Lookup.numGotten æC æKY NBPconfirmAddr æFc AppleTalk.h æT #define æD #define NBPconfirmAddr NBP.parm.Confirm.confirmAddr æC æKY NBPnKillQEl æFc AppleTalk.h æT #define æD #define NBPnKillQEl NBPKILL.nKillQEl æC æKY NBPnewSocket æFc AppleTalk.h æT #define æD #define NBPnewSocket NBP.parm.Confirm.newSocket æC æKY ATPioCompletion æFc AppleTalk.h æT #define æD #define ATPioCompletion ATP.ioCompletion æC æKY ATPioResult æFc AppleTalk.h æT #define æD #define ATPioResult ATP.ioResult æC æKY ATPuserData æFc AppleTalk.h æT #define æD #define ATPuserData ATP.userData æC æKY ATPreqTID æFc AppleTalk.h æT #define æD #define ATPreqTID ATP.reqTID æC æKY ATPioRefNum æFc AppleTalk.h æT #define æD #define ATPioRefNum ATP.ioRefNum æC æKY ATPcsCode æFc AppleTalk.h æT #define æD #define ATPcsCode ATP.csCode æC æKY ATPatpSocket æFc AppleTalk.h æT #define æD #define ATPatpSocket ATP.atpSocket æC æKY ATPatpFlags æFc AppleTalk.h æT #define æD #define ATPatpFlags ATP.atpFlags æC æKY ATPaddrBlock æFc AppleTalk.h æT #define æD #define ATPaddrBlock ATP.addrBlock æC æKY ATPreqLength æFc AppleTalk.h æT #define æD #define ATPreqLength ATP.reqLength æC æKY ATPreqPointer æFc AppleTalk.h æT #define æD #define ATPreqPointer ATP.reqPointer æC æKY ATPbdsPointer æFc AppleTalk.h æT #define æD #define ATPbdsPointer ATP.bdsPointer æC æKY ATPtimeOutVal æFc AppleTalk.h æT #define æD #define ATPtimeOutVal SREQ.timeOutVal æC æKY ATPnumOfResps æFc AppleTalk.h æT #define æD #define ATPnumOfResps SREQ.numOfResps æC æKY ATPretryCount æFc AppleTalk.h æT #define æD #define ATPretryCount SREQ.retryCount æC æKY ATPnumOfBuffs æFc AppleTalk.h æT #define æD #define ATPnumOfBuffs OTH1.u0.numOfBuffs æC æKY ATPbitMap æFc AppleTalk.h æT #define æD #define ATPbitMap OTH1.u0.bitMap æC æKY ATPrspNum æFc AppleTalk.h æT #define æD #define ATPrspNum OTH1.u0.rspNum æC æKY ATPbdsSize æFc AppleTalk.h æT #define æD #define ATPbdsSize OTH2.bdsSize æC æKY ATPtransID æFc AppleTalk.h æT #define æD #define ATPtransID OTH2.transID æC æKY ATPaKillQEl æFc AppleTalk.h æT #define æD #define ATPaKillQEl KILL.aKillQEl æC æKY atpXOvalue æFc AppleTalk.h æT #define æD #define atpXOvalue 32 /*ATP exactly-once bit */ æC æKY atpEOMvalue æFc AppleTalk.h æT #define æD #define atpEOMvalue 16 /*ATP End-Of-Message bit */ æC æKY atpSTSvalue æFc AppleTalk.h æT #define æD #define atpSTSvalue 8 /*ATP Send-Transmission-Status bit */ æC æKY atpTIDValidvalue æFc AppleTalk.h æT #define æD #define atpTIDValidvalue 2 /*ATP trans. ID valid bit */ æC æKY atpSendChkvalue æFc AppleTalk.h æT #define æD #define atpSendChkvalue 1 /*ATP send checksum bit */ æC æKY LAPMgrPtr æFc AppleTalk.h æT #define æD #define LAPMgrPtr 0xB18 /*Entry point for LAP Manager*/ æC æKY LAPMgrCall æFc AppleTalk.h æT #define æD #define LAPMgrCall 2 /*Offset to LAP routines*/ æC æKY ABCallType tLAPRead tLAPWrite tDDPRead tDDPWrite tNBPLookup tNBPConfirm tNBPRegister tATPSndRequest tATPGetRequest tATPSdRsp tATPAddRsp tATPRequest tATPResponse æFc AppleTalk.h æT enum æD enum {tLAPRead,tLAPWrite,tDDPRead,tDDPWrite,tNBPLookup,tNBPConfirm,tNBPRegister, tATPSndRequest,tATPGetRequest,tATPSdRsp,tATPAddRsp,tATPRequest,tATPResponse}; typedef unsigned char ABCallType; æC æKY ABProtoType lapProto ddpProto nbpProto atpProto æFc AppleTalk.h æT enum æD enum {lapProto,ddpProto,nbpProto,atpProto}; typedef unsigned char ABProtoType; æC æKY ABByte . æFc AppleTalk.h æT typedef æD typedef unsigned char ABByte; æC æKY BitMapType æFc AppleTalk.h æT typedef æD typedef char BitMapType; æC æKY Str32 æFc AppleTalk.h æT typedef æD typedef char Str32[33]; æC æKY LAPAdrBlock æFc AppleTalk.h æT struct æD struct LAPAdrBlock { unsigned char dstNodeID; unsigned char srcNodeID; ABByte lapProtType; }; typedef struct LAPAdrBlock LAPAdrBlock; æC æKY ATQEntry æFc AppleTalk.h æT struct æD struct ATQEntry { QElemPtr qLink; /*next queue entry*/ Integer qType; /*queue type*/ ProcPtr CallAddr; /*Pointer to your routine*/ }; typedef struct ATQEntry ATQEntry; typedef ATQEntry *ATQEntry; æC æKY AddrBlock æFc AppleTalk.h æT struct æD struct AddrBlock { short aNet; unsigned char aNode; unsigned char aSocket; }; typedef struct AddrBlock AddrBlock; æC æKY EntityName EntityPtr æFc AppleTalk.h æT struct æD struct EntityName { Str32 objStr; char pad1; /*Str32's aligned on even word boundries.*/ Str32 typeStr; char pad2; Str32 zoneStr; char pad3; }; typedef struct EntityName EntityName; typedef EntityName *EntityPtr; /* Real definition of EntityName is 3 PACKED strings of any length (32 is just an example). No offests for Asm since each String address must be calculated by adding length byte to last string ptr. In Pascal, String(32) will be 34 bytes long since fields never start on an odd byte unless they are only a byte long. So this will generate correct looking interfaces for Pascal and C, but they will not be the same, which is OK since they are not used. */ æC \* Real definition of EntityName is 3 PACKED strings of any length (32 is just an example). No offsets for Asm since each String address must be calculated by adding length byte to last string ptr. In Pascal, String(32) will be 34 bytes long since fields never start on an odd byte unless they are only a byte long. So this will generate correct looking interfaces for Pascal and C, but they will not be the same, which is OK since they are not used. */ æKY RetransType æFc AppleTalk.h æT struct æD struct RetransType { unsigned char retransInterval; unsigned char retransCount; }; typedef struct RetransType RetransType; æC æKY BDSElement æFc AppleTalk.h æT struct æD struct BDSElement { short buffSize; Ptr buffPtr; short dataSize; long userBytes; }; typedef struct BDSElement BDSElement; typedef BDSElement BDSType[8]; typedef BDSType *BDSPtr; æC æKY ATLAPRec ATLAPRecPtr ATLAPRecHandle æFc AppleTalk.h æT struct æD struct ATLAPRec { ABCallType abOpcode; short abResult; long abUserReference; LAPAdrBlock lapAddress; short lapReqCount; short lapActCount; Ptr lapDataPtr; }; typedef struct ATLAPRec ATLAPRec; typedef ATLAPRec *ATLAPRecPtr, **ATLAPRecHandle; æC æKY ATDDPRec ATDDPRecPtr ATDDPRecHandle æFc AppleTalk.h æT struct æD struct ATDDPRec { ABCallType abOpcode; short abResult; long abUserReference; short ddpType; short ddpSocket; AddrBlock ddpAddress; short ddpReqCount; short ddpActCount; Ptr ddpDataPtr; short ddpNodeID; }; typedef struct ATDDPRec ATDDPRec; typedef ATDDPRec *ATDDPRecPtr, **ATDDPRecHandle; æC æKY ATNBPRec ATNBPRecPtr ATNBPRecHandle æFc AppleTalk.h æT struct æD struct ATNBPRec { ABCallType abOpcode; short abResult; long abUserReference; EntityPtr nbpEntityPtr; Ptr nbpBufPtr; short nbpBufSize; short nbpDataField; AddrBlock nbpAddress; RetransType nbpRetransmitInfo; }; typedef struct ATNBPRec ATNBPRec; typedef ATNBPRec *ATNBPRecPtr, **ATNBPRecHandle; æC æKY ATATPRec ATATPRecPtr ATATPRecHandle æFc AppleTalk.h æT struct æD struct ATATPRec { ABCallType abOpcode; short abResult; long abUserReference; short atpSocket; AddrBlock atpAddress; short atpReqCount; Ptr atpDataPtr; BDSPtr atpRspBDSPtr; BitMapType atpBitMap; short atpTransID; short atpActCount; long atpUserData; Boolean atpXO; Boolean atpEOM; short atpTimeOut; short atpRetries; short atpNumBufs; short atpNumRsp; short atpBDSSize; long atpRspUData; Ptr atpRspBuf; short atpRspSize; }; typedef struct ATATPRec ATATPRec; typedef ATATPRec *ATATPRecPtr, **ATATPRecHandle; æC æKY AFPCommandBlock æFc AppleTalk.h æT struct æD typedef struct { char cmdByte; char startEndFlag; short forkRefNum; long rwOffset; long reqCount; char newLineFlag; char newLineChar; }AFPCommandBlock; æC æKY XPPPBHeader æFc AppleTalk.h æT struct æD #define XPPPBHeader \ QElem *qLink; short qType; short ioTrap; Ptr ioCmdAddr; ProcPtr ioCompletion; OSErr ioResult; long cmdResult; short ioVRefNum; short ioRefNum; short csCode; æC æKY XPPPrmBlk æFc AppleTalk.h æT struct æD typedef struct { XPPPBHeader short sessRefnum; /*Offset to session refnum*/ char aspTimeout; /*Timeout for ATP*/ char aspRetry; /*Retry count for ATP*/ short cbSize; /*Command block size*/ Ptr cbPtr; /*Command block pointer*/ short rbSize; /*Reply buffer size*/ Ptr rbPtr; /*Reply buffer pointer*/ short wdSize; /*Write Data size*/ Ptr wdPtr; /*Write Data pointer*/ char ccbStart[296]; /*CCB memory allocated for driver afpWrite max size(CCB)=296 all other calls=150*/ }XPPPrmBlk; æC æKY AFPLoginPrm æFc AppleTalk.h æT struct æD typedef struct { XPPPBHeader short sessRefnum; /*Offset to session refnum */ char aspTimeout; /*Timeout for ATP */ char aspRetry; /*Retry count for ATP */ short cbSize; /*Command block size */ Ptr cbPtr; /*Command block pointer */ short rbSize; /*Reply buffer size */ Ptr rbPtr; /*Reply buffer pointer */ AddrBlock afpAddrBlock; /*block in AFP login */ Ptr afpSCBPtr; /*SCB pointer in AFP login */ Ptr afpAttnRoutine; /*routine pointer in AFP login */ char ccbFill[144]; /*CCB memory allocated for driver Login needs only 150 bytes BUT CCB really starts in the middle of AFPSCBPtr and also clobbers AFPAttnRoutine. */ }AFPLoginPrm; æC æKY ASPOpenPrm ASPOpenPrmPtr æFc AppleTalk.h æT struct æD typedef struct { XPPPBHeader short sessRefnum; /*Offset to session refnum */ char aspTimeout; /*Timeout for ATP */ char aspRetry; /*Retry count for ATP */ AddrBlock serverAddr; /*Server address block */ Ptr scbPointer; /*SCB pointer */ Ptr attnRoutine; /*Attention routine pointer*/ }ASPOpenPrm; typedef ASPOpenPrm *ASPOpenPrmPtr; æC æKY ASPAbortPrm æFc AppleTalk.h æT struct æD typedef struct { XPPPBHeader Ptr abortSCBPtr; /*SCB pointer for AbortOS */ }ASPAbortPrm; æC æKY ASPGetparmsBlk æFc AppleTalk.h æT struct æD typedef struct { XPPPBHeader short aspMaxCmdSize; /*For SPGetParms*/ short aspQuantumSize; short numSesss; }ASPGetparmsBlk; æC æKY WDSElement æFc AppleTalk.h æT struct æD typedef struct { short entryLength; Ptr entryPtr; }WDSElement; æC æKY NTElement æFc AppleTalk.h æT struct æD typedef struct { AddrBlock nteAddress; /*network address of entity*/ char filler; char entityData[99]; /*Object, Type & Zone*/ }NTElement; æC æKY NamesTableEntry æFc AppleTalk.h æT struct æD typedef struct { Ptr qNext; /*ptr to next NTE*/ NTElement nt; }NamesTableEntry; æC æKY MPPATPHeader æFc AppleTalk.h æT struct æD #define MPPATPHeader \ QElem *qLink; /*next queue entry*/ short qType; /*queue type*/ short ioTrap; /*routine trap*/ Ptr ioCmdAddr; /*routine address*/ ProcPtr ioCompletion; /*completion routine*/ OSErr ioResult; /*result code*/ long userData; /*Command result (ATP user bytes)*/ short reqTID; /*request transaction ID*/ short ioRefNum; /*driver reference number*/ short csCode; /*Call command code*/ æC æKY MPPparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader }MPPparms; æC æKY LAPparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader char protType; /*ALAP protocol Type */ char filler; union { Ptr wdsPointer; /*-> write data structure*/ Ptr handler; /*-> protocol handler routine*/ } LAPptrs; }LAPparms; æC æKY DDPparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader char socket; /*socket number */ char checksumFlag; /*check sum flag */ union { Ptr wdsPointer; /*-> write data structure*/ Ptr listener; /*->write data structure or -> Listener*/ } DDPptrs; }DDPparms; æC æKY NBPparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader char interval; /*retry interval */ char count; /*retry count */ union { Ptr ntQElPtr; Ptr entityPtr; } NBPPtrs; union { char verifyFlag; struct { Ptr retBuffPtr; short retBuffSize; short maxToGet; short numGotten; } Lookup; struct { AddrBlock confirmAddr; char newSocket; } Confirm; } parm; }NBPparms; æC æKY SetSelfparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader char newSelfFlag; /*self-send toggle flag */ char oldSelfFlag; /*previous self-send state */ }SetSelfparms; æC æKY NBPKillparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader Ptr nKillQEl; /*ptr to i/o queue element to cancel */ }NBPKillparms; æC æKY MPPParamBlock MPPPBPtr æFc AppleTalk.h æT struct æD typedef union { MPPparms MPP; /*General MPP parms*/ LAPparms LAP; /*ALAP calls*/ DDPparms DDP; /*DDP calls*/ NBPparms NBP; /*NBP calls*/ SetSelfparms SETSELF ; NBPKillparms NBPKILL ; }MPPParamBlock; typedef MPPParamBlock *MPPPBPtr; æC æKY MOREATPHeader æFc AppleTalk.h æT struct æD #define MOREATPHeader \ char atpSocket; /*currbitmap for requests or ATP socket number*/ char atpFlags; /*control information*/ AddrBlock addrBlock; /*source/dest. socket address*/ short reqLength; /*request/response length*/ Ptr reqPointer; /*->request/response Data*/ Ptr bdsPointer; /*->response BDS */ æC æKY ATPparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader MOREATPHeader }ATPparms; æC æKY SendReqparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader MOREATPHeader char filler; /*numOfBuffs */ char timeOutVal; /*timeout interval */ char numOfResps; /*number of responses actually received */ char retryCount; /*number of retries */ short intBuff; /*used internally for NSendRequest */ }SendReqparms; æC æKY ATPmisc1 æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader MOREATPHeader union { char bitMap; /*bitmap received */ char numOfBuffs; /*number of responses being sent*/ char rspNum; /*sequence number*/ } u0; }ATPmisc1; æC æKY ATPmisc2 æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader MOREATPHeader char filler; char bdsSize; /*number of BDS elements */ short transID; /*transaction ID recd. */ }ATPmisc2; æC æKY Killparms æFc AppleTalk.h æT struct æD typedef struct { MPPATPHeader MOREATPHeader Ptr aKillQEl; /*ptr to i/o queue element to cancel*/ }Killparms; æC æKY ATPParamBlock ATPPBPtr æFc AppleTalk.h æT struct æD typedef union { ATPparms ATP; /*General ATP parms*/ SendReqparms SREQ; /*sendrequest parms*/ ATPmisc1 OTH1; /*and a few others*/ ATPmisc2 OTH2; /*and a few others*/ Killparms KILL; /*and a few others */ }ATPParamBlock; typedef ATPParamBlock *ATPPBPtr; æC æKY XPPParamBlock XPPParmBlkPtr æFc AppleTalk.h æT struct æD typedef union { XPPPrmBlk XPP; ASPGetparmsBlk GETPARM; ASPAbortPrm ABORT; ASPOpenPrm OPEN; AFPLoginPrm LOGIN; }XPPParamBlock; typedef XPPParamBlock *XPPParmBlkPtr; æC æKY OpenXPP æFc AppleTalk.h æT Function æD pascal OSErr OpenXPP(short *xppRefnum); æDT OSErr myVariable = OpenXPP((short *) xppRefnum); æRI æC »Opening the .XPP Driver To open the .XPP driver, issue a Device Manager Open call. (Refer to the Device Manager chapter.) The name of the .XPP driver is '.XPP'. The original Macintosh ROMs require that .XPP be opened only once. With new ROMs, the .XPP unit number can always be obtained through an Open call. With old ROMs only, the .XPP unit number must be hard coded to XPPUnitNum (40) since only one Open call can be issued to the driver. The .XPP driver cannot be opened unless AppleTalk is open. The application must ensure that the .MPP and .ATP drivers are opened, as described earlier in this chapter. The xppLoaded bit (bit 5) in the PortBUse byte in low memory indicates whether or not the .XPP driver is open. »Example The following is an example of the procedure an application might use to open the .XPP driver. ; Routine: OpenXPP ; ; Open the .XPP driver and return the driver refNum for it. ; ; Exit: D0 = error code (ccr's set) ; D1 = XPP driver refNum (if no errors) ; ; All other registers preserved ; xppUnitNum EQU 40 ;default XPP driver number xppTfRNum EQU -(xppUnitNum+1) ;default XPP driver refNum OpenXPP MOVE.L A0-A1/D2,-(SP) ;save registers MOVE ROM85,D0 ;check ROM type byte BPL.S @10 ;branch if >=128K ROMs BTST #xppLoadedBit,PortBUse ;is the XPP driver open already? BEQ.S @10 ;if not open, then branch to Open code MOVE #xppTfRNum,D1 ;else use this as driver refnum MOVEQ #0,D0 ;set noErr BRA.S @90 ;and exit ; ; XPP driver not open. Make an _Open call to it. If using a 128K ; ROM machine and the driver is already open, we will make another ; Open call to it just so we get the correct driver refNum. ; @10 SUB #ioQElSize,SP ;allocate temporary param block MOVE.L SP,A0 ;A0 -> param block LEA XPPName, A1 ;A1 -> XPP (ASP/AFP) driver name MOVE.L A1,ioFileName(A0) ;driver name into param block CLR.B ioPermssn(A0) ;clear permissions byte _Open MOVE ioRefNum(A0),D1 ;D1=driver refNum (invalid if error) ADD #ioQElSize,SP ;deallocate temp param block @90 MOVE.L (SP)+,A0-A1/D2 ;restore registers TST D0 ;error? (set ccr's) RTS XPPName DC.B 4 ;length of string DC.B '.XPP' ;driver name From Pascal, XPP can be opened through the OpenXPP call, which returns the driver’s reference number: FUNCTION OpenXPP (VAR xppRefnum: INTEGER) : OSErr; »Open Errors Errors returned when calling the Device Manager Open routine if the function does not execute properly include the following: • errors returned by System • portInUse is returned if the AppleTalk port is in use by a driver other than AppleTalk or if AppleTalk is not open. »Closing the .XPP Driver To close the .XPP driver, call the Device Manager Close routine. Warning: There is generally no reason to close the driver. Use this call sparingly, if at all. This call should generally be used only by system-level applications. »Close Errors Errors returned when calling the Device Manager Close routine if the function does not execute properly include the following: • errors returned by System • closeErr (new ROMs only) is returned if you try to close the driver and there are sessions active through that driver. When sessions are active, closeErr is returned and the driver remains open. • on old ROMs the driver is closed whether or not sessions are active and no error is returned. Results are unpredictable if sessions are still active. »Session Control Block The session control block (SCB) is a nonrelocatable block of data passed by the caller to XPP upon session opening. XPP reserves this block for use in maintaining an open session. The SCB size is defined by the constant scbMemSize. The SCB is a locked block, and as long as the session is open, the SCB cannot be modified in any way by the application. There is one SCB for each open session. This block can be reused once a CloseSess call is issued and completed for that session or when the session is indicated as closed. æKY ASPOpenSession æFc AppleTalk.h æT Function æD pascal OSErr ASPOpenSession(ASPOpenPrmPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPOpenSession((ASPOpenPrmPtr) thePBptr,(Boolean) async); æRI V-536 æC »AppleTalk Session Protocol Functions This section contains descriptions of the .XPP driver functions that you can call. Each function description shows the required parameter block fields, their offsets within the parameter block and a brief definition of the field. Possible result codes are also described. »Note on Result Codes An important distinction exists between the aspParamErr and aspSessClose result codes that may be returned by the .XPP driver. When the driver returns aspParamErr to a call that takes as an input a session reference number, the session reference number does not relate to a valid open session. There could be several reasons for this, such as the workstation or server end closed the session or the server end of the session died. The aspSessClosed result code indicates that even though the session reference number relates to a valid session, that particular session is in the process of closing down (although the session is not yet closed). FUNCTION ASPOpenSession (xParamBlock: XPPParmBlkPtr; async: BOOLEAN) : OSErr; Parameter block --> 26 csCode word Always ASPOpenSess --> 28 sessRefnum word Session reference number --> 30 aspTimeout byte Retry interval in seconds --> 31 aspRetry byte Number of retries --> 32 serverAddr long word Server socket address --> 36 scbPointer pointer Pointer to session control block --> 40 attnRoutine pointer Pointer to attention routine ASPOpenSession initiates (opens) a session between the workstation and a server. The required parameter block is shown above. A brief definition of the fields follows. SessRefnum is a unique number identifying the open session between the workstation and the server. The SessRefnum is returned when the function completes successfully and is used in all calls to identify the session. ASPTimeOut is the interval in seconds between retries of the open session request. ASPRetry is the number of retries that will be attempted. ServerAddr is the network identifier or address of the socket on which the server is listening. SCBPointer points to a nonrelocatable block of data for the session control block (SCB) that the .XPP driver reserves for use in maintaining an open session. The SCB size is defined by the constant scbMemSize. The SCB is a locked block and as long as the session is open, the SCB cannot be modified in any way by the application. There is one SCB for each open session. This block can be reused when a CloseSess call is issued and completed for that session, or when the session is indicated as closed through return of aspParamErr as the result of a call for that session. AttnRoutine is a pointer to a routine that is invoked if an attention from the server is received, or upon session closing. If this pointer is equal to zero, no attention routine will be invoked. Result codes aspNoMoreSess Driver cannot support another session aspParamErr Server returned bad (positive) error code aspNoServers No servers at that address, or the server did not respond to the request reqAborted OpenSess was aborted by an AbortOS aspBadVersNum Server cannot support the offered version number aspServerBusy Server cannot open another session Note: The number of sessions that the driver is capable of supporting depends on the machine that the driver is running on. æKY ASPCloseSession æFc AppleTalk.h æT Function æD pascal OSErr ASPCloseSession(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPCloseSession((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-537 æC Parameter block --> 26 csCode word Always ASPCloseSession --> 28 sessRefnum word Session reference number ASPCloseSession closes the session identified by the sessRefnum returned in the ASPOpenSession call. ASPCloseSession aborts any calls that are active on the session, closes the session, and calls the attention routine, if any, with an attention code of zero (zero is invalid as a real attention code). Result codes aspParamErr Parameter error, indicates an invalid session reference number aspSessClosed Session already in process of closing æKY ASPAbortOS æFc AppleTalk.h æT Function æD pascal OSErr ASPAbortOS(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPAbortOS((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-537 æC Parameter block --> 26 csCode word Always ASPAbortOS --> 28 abortSCBPointer pointer Pointer to session control block ASPAbortOS aborts a pending (not yet completed) ASPOpenSession call. The aborted ASPOpenSession call will return a reqAborted error. AbortSCBPointer points to the original SCB used in the the pending ASPOpenSession call. Result codes cbNotFound SCB not found, no outstanding open session to be aborted. Pointer did not point to an open session SCB. æKY ASPGetParms æFc AppleTalk.h æT Function æD pascal OSErr ASPGetParms(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPGetParms((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-538 æC Parameter block --> 26 csCode word Always ASPGetParms --> 28 aspMaxCmdSize word Maximum size of command block --> 30 aspQuantumSize word Maximum data size --> 32 numSesss word Number of sessions ASPGetParms returns three ASP parameters. This call does not require an open session. ASPMaxCmdSize is the maximum size of a command that can be sent to the server. ASPQuantumSize is the maximum size of data that can be transferred to the server in a Write request or from the server in a command reply. NumSess is the number of concurrent sessions supported by the driver. æKY ASPCloseAll æFc AppleTalk.h æT Function æD pascal OSErr ASPCloseAll(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPCloseAll((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-538 æC Parameter block --> 26 csCode word Always ASPCloseAll ASPCloseAll closes every session that the driver has active, aborting all active requests and invoking the attention routines where provided. This call should be used carefully. ASPCloseAll can be used as a system level resource for making sure all sessions are closed prior to closing the driver. æKY ASPUserWrite æFc AppleTalk.h æT Function æD pascal OSErr ASPUserWrite(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPUserWrite((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-538 æC Parameter block --> 18 cmdResult long word ASP command result --> 26 csCode word Always UserWrite --> 28 sessRefnum word Session reference number --> 30 aspTimeout byte Retry interval in seconds --> 32 cbSize word Command block size --> 34 cbPtr pointer Command block pointer <-> 38 rbSize word Reply buffer size and reply size --> 40 rbPtr pointer Reply buffer pointer <-> 44 wdSize word Write data size --> 46 wdPtr pointer Write data pointer --> 50 ccbStart record Start of memory for CCB ASPUserWrite transfers data on a session. ASPUserWrite is one of the two main calls that can be used to transfer data on an ASP session. The other call that performs a similar data transfer is ASPUserCommand described below. The ASPUserWrite command returns data in two different places. Four bytes of data are returned in the cmdResult field and a variable size reply buffer is also returned. CmdResult is four bytes of data returned by the server. SessRefnum is the session reference number returned in the ASPOpenSession call. ASPTimeOut is the interval in seconds between retries of the call. Notice that there is no aspRetry field (retries are infinite). The command will be retried at the prescribed interval until completion or the session is closed. CBSize is the size in bytes of the command data that is to be written on the session. The size of the command block must not exceed the value of aspMaxCmdSize returned by the ASPGetParms call. Note that this buffer is not the data to be written by the command but only the data of the command itself. CBPtr points to the command data. RBSize is passed and indicates the size of the reply buffer in bytes expected by the command. RBSize is also returned and indicates the size of the reply that was actually returned. RBPtr points to the reply buffer. WDSize is passed and indicates the size of the write data in bytes to be sent by the command. WDSize is also returned and indicates the size of the write data that was actually written. WDPointer points to the write data buffer. CCBStart is the start of the memory to be used by the .XPP driver for the command control block. The size of this block is equal to a maximum of 296 bytes. To determine the exact requirement, refer to the CCB Sizes section of this document. Result codes aspParamErr Invalid session number, session has been closed aspSizeErr Command block size is bigger than MaxCmdSize aspSessClosed Session is closing aspBufTooSmall Reply is bigger than response buffer; the buffer will be filled, data will be truncated æKY ASPUserCommand æFc AppleTalk.h æT Function æD pascal OSErr ASPUserCommand(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPUserCommand((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-539 æC Parameter block --> 18 cmdResult long word ASP command result --> 26 csCode word Always ASPUserCommand --> 28 sessRefnum word Session number --> 30 aspTimeout byte Retry interval in seconds --> 32 cbSize word Command block size --> 34 cbPtr pointer Command block pointer <-> 38 rbSize word Reply buffer and reply size --> 40 rbPtr pointer Reply buffer pointer --> 50 ccbStart record Start of memory for CCB ASPUserCommand is used to send a command to the server on a session. SessRefnum is the session reference number returned in the ASPOpenSession call. ASPTimeOut is the interval in seconds between retries of the call. Notice that there is no aspRetry field (retries are infinite). The command will be retried at the prescribed interval until completion or the session is closed. CBSize is the size in bytes of the block of data that contains the command to be sent to the server on the session. The size of the command block must not exceed the value of aspMaxCmdSize returned by the ASPGetParms call. CBPointer points to the block of data containing the command that is to be sent to the server on the session. RBSize is passed and indicates the size of the reply buffer in bytes expected by the command. RBSize is also returned and indicates the size of the reply that was actually returned. RBPtr points to the reply buffer. CCBStart is the start of the memory to be used by the .XPP driver for the command control block. The size of this block is equal to a maximum of 150 bytes. To determine the exact requirement refer to the CCB Sizes section of this document. Result codes aspParamErr Invalid session number, session has been closed aspSizeErr Command block size is bigger than MaxCmdSize aspSessClosed Session is closing aspBufTooSmall Reply is bigger than response buffer; the buffer will be filled, data will be truncated æKY ASPGetStatus æFc AppleTalk.h æT Function æD pascal OSErr ASPGetStatus(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = ASPGetStatus((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-540 æC Parameter block --> 26 csCode word Always ASPGetStatus --> 30 aspTimeout byte Retry interval in seconds --> 31 aspRetry byte Number of retries --> 32 serverAddr long word Server socket address <-> 38 rbSize word Reply buffer and reply size --> 40 rbPtr pointer Reply buffer pointer --> 50 ccbStart record Start of memory for CCB ASPGetStatus returns server status. This call is also used as GetServerInfo at the AFP level. This call is unique in that it transfers data over the network without having a session open. This call does not pass any data but requests that server status be returned. ASPTimeOut is the interval in seconds between retries of the call. ASPRetry is the number of retries that will be attempted. ServerAddr is the network identifier or address of the socket on which the server is listening. RBSize is passed and indicates the size of the reply buffer in bytes expected by the command. RBSize is also returned and indicates the size of the reply that was actually returned. RBPtr points to the reply buffer. CCBStart is the start of the memory to be used by the .XPP driver for the command control block. The size of this block is equal to a maximum of 150 bytes. To determine the exact requirement refer to the CCB Sizes section of this document. Result codes aspBufTooSmall Reply is bigger than response buffer, or Replysize is bigger than ReplyBuffsize aspNoServer No response from server at address used in call æKY AFPCommand æFc AppleTalk.h æT Function æD pascal OSErr AFPCommand(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = AFPCommand((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI V-542 æC »AFPCall Function The AFPCall function can have one of the following command formats. • General • Login • AFPWrite • AFPRead »General Command Format FUNCTION AFPCommand (xParamBlock: XPPParmBlkPtr; async: BOOLEAN) : OSErr; Parameter block --> 18 cmdResult long word AFP command result --> 26 csCode word Always AFPCall --> 28 sessRefnum word Session reference number --> 30 aspTimeout byte Retry interval in seconds --> 32 cbSize word Command buffer size --> 34 cbPtr pointer Command buffer <-> 38 rbSize word Reply buffer size and reply size --> 40 rbPtr pointer Reply buffer pointer <-> 44 wdSize word Write data size --> 46 wdPtr pointer Write data pointer --> 50 ccbStart record Start of memory for CCB The general command format for the AFPCall function passes an AFP command to the server. This format is used for all AFP calls except AFPLogin, AFPRead, and AFPWrite. Note that from Pascal this call is referred to as AFPCommand. CmdResult is four bytes of data returned from the server containing an indication of the result of the AFP command. SessRefnum is the session reference number returned in the AFPLogin call. ASPTimeOut is the interval in seconds between retries of the call by the driver. CBSize is the size in bytes of the block of data that contains the command to be sent to the server on the session. The size of the command block must not exceed the value of aspMaxCmdSize returned by the ASPGetParms call. CBPtr points to start of the block of data (command block) containing the command that is to be sent to the server on the session. The first byte of the command block must contain the AFP command byte. Subsequent bytes in the command buffer contain the parameters associated with the command as defined in the AFP document. RBSize is passed and indicates the size of the reply buffer in bytes expected by the command. RBSize is also returned and indicates the size of the reply that was actually returned. RBPtr points to the reply buffer. WDSize is the size of data to be written to the server (only used if the command is one that is mapped to an ASPUserWrite). WDPtr points to the write data buffer (only used if the command is one that is mapped to an ASPUserWrite). CCBStart is the start of the memory to be used by the .XPP driver for the command control block. The size of this block is equal to a maximum of 296 bytes. To determine the exact requirement refer to the CCB Sizes section of this document. Result codes aspParamErr Invalid session number; session has been closed aspSizeErr Command block size is bigger than MaxCmdSize aspSessClosed Session is closing aspBufTooSmall Reply is bigger than response buffer or buffer will be filled, data will be truncated afpParmError AFP command block size is equal to zero. This error will also be returned if the command byte in the command block is equal to 0 or $FF (255) or GetSrvrStatus (15). »Login Command Format The AFP login command executes a series of AFP operations as defined in the AFP Draft Proposal. For further information, refer to the AFP document. FUNCTION AFPCommand (xParamBlock: XPPParmBlkPtr; async: BOOLEAN): OSErr; Parameter block --> 18 cmdResult long word AFP command result --> 26 csCode word Always AFPCall --> 28 sessRefnum word Session reference number --> 30 aspTimeout byte Retry interval in seconds --> 31 aspRetry byte Number of retries --> 32 cbSize word Command buffer size --> 34 cbPtr pointer Command buffer <-> 38 rbSize word Reply buffer size and reply size --> 40 rbPtr pointer Reply buffer pointer --> 44 afpAddrBlock long word Server address block <-> 48 afpSCBPtr pointer SCB pointer <-> 52 afpAttnRoutine pointer Attention routine pointer --> 50 ccbStart record Start of command control block CmdResult is four bytes of data returned from the server containing an indication of the result of the AFP command. SessRefnum is the session reference number (returned by the AFPLogin call). ASPTimeOut is the interval in seconds between retries of the call. ASPRetry is the number of retries that will be attempted. CBSize is the size in bytes of the block data that contains the command to be sent to the server on the session. The size of the command block must not exceed the value of aspMaxCmdSize returned by the ASPGetParms call. CBPtr points to the block of data (command block) containing the AFP login command that is to be sent to the server on the session. The first byte of the command block must be the AFP login command byte. Subsequent bytes in the command buffer contain the parameters associated with the command. RBSize is passed and indicates the size of the reply buffer in bytes expected by the command. RBSize is also returned and indicates the size of the reply that was actually returned. RBPtr points to the reply buffer. AFPServerAddr is the network identifier or address of the socket on which the server is listening. AFPSCBPointer points to a locked block of data for the session control block (SCB). The SCB size is defined by scbMemSize. The SCB is a locked block, and as long as the session is open, the SCB cannot be modified in any way by the application. There is one SCB for each open session. AFPAttnRoutine is a pointer to a routine that is invoked if an attention from the server is received. When afpAttnRoutine is equal to zero, no attention routine will be invoked. CCBStart is the start of the memory to be used by the .XPP driver for the command control block. The size of this block is equal to a maximum of 150 bytes. To determine the exact requirement refer to the CCB Sizes section later in this chapter. Note: In the parameter block, the afpSCBPointer and the afpAttnRoutine fields overlap with the start of the CCB and are modified by the call. Result codes aspSizeErr Command block size is bigger than MaxCmdSize aspBufTooSmall Reply is bigger than response buffer or buffer will be filled, data will be truncated aspNoServer Server not responding aspServerBusy Server cannot open another session aspBadVersNum Server cannot support the offered ASP version number aspNoMoreSess Driver cannot support another session. »AFPWrite Command Format The AFPWrite and AFPRead command formats allow the calling application to make AFP-level calls that read or write a data block that is larger than a single ASP-level call is capable of reading or writing. The maximum number of bytes of data that can be read or written at the ASP level is equal to quantumSize. FUNCTION AFPCommand (xParamBlock: XPPParmBlkPtr; async: BOOLEAN) : OSErr; Parameter block --> 18 cmdResult long word AFP command result --> 26 csCode word Always AFPCall --> 28 sessRefnum word Session number --> 30 aspTimeout byte Retry interval in seconds --> 32 cbSize word Command buffer size --> 34 cbPtr pointer Command buffer <-> 38 rbSize word Reply buffer size and reply size --> 40 rbPtr pointer Reply buffer pointer --> 44 wdSize word (used internally) <-> 46 wdPtr pointer Write data pointer (updated) --> 50 ccbStart record Start of memory for CCB CmdResult is four bytes of data returned from the server containing an indication of the result of the AFP command. SessRefnum is the session reference number returned in the AFPLogin call. ASPTimeOut is the interval in seconds between retries of the call. CBSize is the size in bytes of the block data that contains the command to be sent to the server on the session. The size of the command block must not exceed the value of aspMaxCmdSize returned by the aspGetParms call. CBPtr points to the block of data (see command block structure below) containing the AFP write command that is to be sent to the server on the session. The first byte of the Command Block must contain the AFP write command byte. RBSize is passed and indicates the size of the reply buffer in bytes expected by the command. RBSize is also returned and indicates the size of the reply that was actually returned. RBPtr points to the reply buffer. WDSize is used internally. Note: This command does not pass the write data size in the queue element but in the command buffer. XPP will look for the size in that buffer. WDPtr is a pointer to the block of data to be written. Note that this field will be updated by XPP as it proceeds and will always point to that section of the data which XPP is currently writing. CCBStart is the start of the memory to be used by the XPP driver for the command control block. The size of this block is equal to a maximum of 296 bytes. To determine the exact requirement refer to the CCB Sizes section later in this chapter. Command Block Structure: The AFP write command passes several arguments to XPP in the command buffer itself. The byte offsets are relative to the location pointed to by cbPtr. --> 0 cmdByte byte AFP call command byte --> 1 startEndFlag byte Start/end Flag <-> 4 rwOffset long word Offset within fork to write <-> 8 reqCount long word Requested count CmdByte is the AFP call command byte and must contain the AFP write command code. StartEndFlag is a one-bit flag (the high bit of the byte) indicating whether the rwOffset field is relative to the beginning or the end of the fork (all other bits are zero). 0 = relative to the beginning of the fork 1 = relative to the end of the fork RWOffset is the byte offset within the fork at which the write is to begin. ReqCount indicates the size of the data to be written and is returned as the actual size written. The rwOffset and reqCount fields are modified by XPP as the write proceeds and will always indicate the current value of these fields. The Pascal structure of the AFP command buffer follows: AFPCommandBlock = PACKED RECORD cmdByte: Byte; startEndFlag: Byte; forkRefNum: INTEGER; {used by server} rwOffset: LONGINT; reqCount: LONGINT; newLineFlag: Byte; {unused by write} newLineChar: CHAR; {unused by write} END; Result codes aspParamErr Invalid session number aspSizeErr Command block size is bigger than MaxCmdSize aspSessClosed Session is closing aspBufTooSmall Reply is bigger than response buffer »AFPRead Command Format The AFPWrite and AFPRead command formats allow the calling application to make AFP-level calls that read or write a data block that is larger than a single ASP-level call is capable of reading or writing. The maximum number of bytes of data that can be read or written at the ASP level is equal to quantumSize. FUNCTION AFPCommand (xParamBlock: XPPParmBlkPtr; async: BOOLEAN) : OSErr; Parameter block --> 18 cmdResult long word ASP command result --> 26 csCode word Always AFPCall --> 28 sessRefnum word Session number --> 30 aspTimeout byte Retry interval in seconds --> 32 cbSize word Command buffer size --> 34 cbPtr pointer Command buffer --> 38 rbSize word Used internally <-> 40 rbPtr pointer Reply buffer pointer (updated) --> 50 ccbStart record Start of memory for CCB CmdResult is four bytes of data returned from the server containing an indication of the result of the AFP command. SessRefnum is the session reference number returned in the AFPLogin call. ASPTimeOut is the interval in seconds between retries of the call. CBSize is the size in bytes of the block data that contains the command to be sent to the server on the session. The size of the command block must not exceed the value of aspMaxCmdSize returned by the GetParms call. CBPtr points to the block of data (command block) containing the AFP read command that is to be sent to the server on the session. The first byte of the command block must contain the AFP read command byte. The command block structure is shown below. RBSize is used internally. Note: This command does not pass the read size in the queue element but in the command buffer. XPP will look for the size in that buffer. RBPtr points to the reply buffer. Note that this field will be updated by XPP as it proceeds and will always point to that section of the buffer that XPP is currently reading into. CCBStart is the start of the memory to be used by the .XPP driver for the command control block. The size of this block is equal to a maximum of 150 bytes. To determine the exact requirement refer to The CCB Sizes section later in this chapter. Command Block Structure: The AFP read command passes several arguments to XPP in the command buffer itself. The byte offsets are relative to the location pointed to by cbPointer. --> 0 cmdByte byte AFP call command byte <-> 4 rwOffset long word Offset within fork to read <-> 8 reqCount long word Requested count --> 12 newLineFlag byte Newline Flag --> 13 newLineChar byte Newline Character CmdByte is the AFP call command byte and must contain the AFP read command code. RWOffset is the byte offset within the fork at which the read is to begin. ReqCount indicates the size of the read data buffer and is returned as the actual size read. The rwOffset and reqCount fields are modified by XPP as the read proceeds and will always indicate the current value of these fields. NewLineFlag is a one-bit flag (the high bit of the byte) indicating whether or not the read is to terminate at a specified character (all other bits are zero). 0 = no Newline Character is specified 1 = a Newline Character is specified NewLineChar is any character from $00 to $FF (inclusive) that, when encountered in reading the fork, causes the read operation to terminate. The Pascal structure of the AFPCommand follows: AFPCommandBlock = PACKED RECORD cmdByte: Byte; startEndFlag: Byte; {unused for read} forkRefNum: INTEGER; {used by server} rwOffset: LONGINT; reqCount: LONGINT; newLineFlag: Byte; newLineChar: CHAR; END; Result codes aspParamErr Invalid session number aspSizeErr Command block size is bigger than MaxCmdSize aspSessClosed Session is closing aspBufTooSmall Reply is bigger than response buffer æKY GetLocalZones æFc AppleTalk.h æT Function æD pascal OSErr GetLocalZones(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = GetLocalZones((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI VI æC Parameter block ¨ 16 ioResult word result code Æ 26 csCode word routine selector; always xCall Æ 28 xppSubCode word routine selector; getLocalZones Æ 30 xppTimeOut byte retry interval in seconds Æ 31 xppRetry byte retry count Æ 34 zipBuffPtr pointer pointer to data buffer ¨ 38 zipNumZones word number of names returned ¨ 40 zipLastFlag byte nonzero if no more names Æ 42 zipInfoField 70 bytes for use by ZIP; first word set to 0 The GetLocalZones function returns a list of all the zone names on the local network; that is, the network that includes the node on which your application is running. The ioResult parameter returns the result of the function; if you call the function asynchronously, the function sets this field to 1 as soon as it begins execution, and changes the field to the actual result code when it completes execution. The csCode and xppSubCode parameters are routine selectors and are automatically set by the MPW interface to xCall and getLocalZones for this function. The xppTimeOut field specifies the amount of time, in seconds, that the .ATP driver should wait between attempts to obtain the data. A value of 3 or 4 for the xppTimeOut field generally gives good results. The xppRetry field specifies the number of times the .ATP driver should attempt to obtain the data before returning the ReqFailed (request failed) result code. A value of 3 or 4 for the xppRetry field usually works well. The zipBuffPtr is a pointer to a 578-byte data buffer that you must allocate. The Zone Information Protocol returns the zone names into this buffer as a packed array of packed Pascal strings. The zipNumZones parameter returns the number of zone names that ZIP placed in the data buffer. The .XPP driver sets the zipLastFlag field to 1 if there are no more zone names for your network. If the zipLastFlag field is still 0 when the GetLocalZones function has completed execution, you must empty the data buffer pointed to by the zipBuffPtr parameter and immediately call the GetLocalZones function again without changing the value in the zipInfoField parameter. The zipInfofield parameter is a 70-byte data buffer that you must allocate for use by ZIP. You must set the first word of this buffer to 0 before you call the GetLocalZones function the first time, and not change the contents of this field thereafter. æKY GetZoneList æFc AppleTalk.h æT Function æD pascal OSErr GetZoneList(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = GetZoneList((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI VI æC Parameter block ¨ 16 ioResult word result code Æ 26 csCode word routine selector; always xCall Æ 28 xppSubCode word routine selector; getZoneList Æ 30 xppTimeOut byte retry interval in seconds Æ 31 xppRetry byte retry count Æ 34 zipBuffPtr pointer pointer to data buffer ¨ 38 zipNumZones word number of names returned ¨ 40 zipLastFlag byte nonzero if no more names Æ 42 zipInfoField 70 bytes for use by ZIP; first word set to 0 The GetZoneList function returns a complete list of all the zone names on the internet. Use the GetLocalZones function to obtain a list of only the zone names on the local network. The ioResult parameter returns the result of the function; if you call the function asynchronously, the function sets this field to 1 as soon as it begins execution, and changes the field to the actual result code when it completes execution. The csCode and xppSubCode parameters are routine selectors and are automatically set by the MPW interface to xCall and getZoneList for this function. The xppTimeOut field specifies the amount of time, in seconds, that the .ATP driver should wait between attempts to obtain the data. A value of 3 or 4 for the xppTimeOut field generally gives good results. The xppRetry field specifies the number of times the .ATP driver should attempt to obtain the data before returning the ReqFailed (request failed) result code. A value of 3 or 4 for the xppRetry field usually works well. The zipBuffPtr is a pointer to a 578-byte data buffer that you must allocate. The Zone Information Protocol returns the zone names into this buffer as Pascal strings. The zipNumZones parameter returns the number of zone names that ZIP placed in the data buffer. The .XPP driver sets the zipLastFlag field to 1 if there are no more zone names for the internet. If the zipLastFlag field is still 0 when the GetZoneList function has completed execution, you must empty the data buffer pointed to by the zipBuffPtr parameter and immediately call the GetZoneList function again without changing the value in the zipInfoField parameter. The zipInfofield parameter is a 70-byte data buffer that you must allocate for use by ZIP. You must set the first word of this buffer to 0 before you call the GetZoneList function the first time, and not change the contents of this field thereafter. æKY GetMyZone æFc AppleTalk.h æT Function æD pascal OSErr GetMyZone(XPPParmBlkPtr thePBptr,Boolean async); æDT OSErr myVariable = GetMyZone((XPPParmBlkPtr) thePBptr,(Boolean) async); æRI VI æC The .XPP driver provides three functions that obtain information about zones. All three functions use the Zone Information Protocol to return the names of zones: The GetMyZone function returns the AppleTalk zone name of the node on which your application is running; the GetLocalZones function returns a list of zone names on the network that includes the node on which your application is running; and the GetZoneList function returns a complete list of zones on the internet. Assembly-language note: The .XPP driver functions all use the same value (xCall, which is equal to 246) for the csCode parameter to the xCallParam parameter block. The xCall routine uses the value of the xppSubCode parameter to distinguish between the functions, as follows: Function xppSubCode Value GetMyZone getMyZone 7 GetLocalZones getLocalZones 5 GetZoneList getZoneList 6 FUNCTION GetMyZone (thePBptr:XCallParamPtr; async: BOOLEAN) : OSErr; Parameter block ¨ 16 ioResult word result code Æ 26 csCode word routine selector; always xCall Æ 28 xppSubCode word routine selector; getMyZone Æ 30 xppTimeOut byte retry interval in seconds Æ 31 xppRetry byte retry count Æ 34 zipBuffPtr long pointer to data buffer Æ 42 zipInfoField 70 bytes for use by ZIP; first word set to 0 The GetMyZone function returns only the zone name of the node on which your application is running. The ioResult parameter returns the result of the function; if you call the function asynchronously, the function sets this field to 1 as soon as it begins execution, and changes the field to the actual result code when it completes execution. The csCode and xppSubCode parameters are routine selectors and are automatically set by the MPW interface to xCall and getMyZone for this function. The xppTimeOut field specifies the amount of time, in seconds, that the .ATP driver should wait between attempts to obtain the data. A value of 3 or 4 for the xppTimeOut field generally gives good results. The xppRetry field specifies the number of times the .ATP driver should attempt to obtain the data before returning the ReqFailed (request failed) result code. A value of 3 or 4 for the xppRetry field usually works well. The zipBuffPtr is a pointer to a 33-byte data buffer that you must allocate. The Zone Information Protocol returns the zone name into this buffer as a Pascal string. The zipInfo field is a 70-byte data buffer that you must allocate for use by ZIP. You must set the first word of this buffer to 0 before you call the GetMyZone function. Result codes noErr 0 no error noBridgeErr –93 no router is available reqFailed –1096 Request to contact router failed; retry count exceeded æKY PAttachPH æFc AppleTalk.h æT Function æD pascal OSErr PAttachPH(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PAttachPH((MPPPBPtr) thePBptr,(Boolean) async); æRI II-308, V-513 æC AttachPH function Parameter block -> 26 csCode word ;always attachPH -> 28 protType byte ;ALAP protocol type -> 30 handler pointer ;protocol handler AttachPH adds the protocol handler pointed to by handler to the node's protocol table. ProtType specifies what kind of frame the protocol handler can service. After AttachPH is called, the protocol handler is called for each incoming frame whose ALAP protocol type equals protType. Result codes noErr No error lapProtErr Error attaching protocol type æKY PDetachPH æFc AppleTalk.h æT Function æD pascal OSErr PDetachPH(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PDetachPH((MPPPBPtr) thePBptr,(Boolean) async); æRI II-308, V-513 æC DetachPH function Parameter block -> 26 csCode word ;always detachPH -> 28 protType byte ;ALAP protocol type DetachPH removes from the node's protocol table the specified ALAP protocol type and corresponding protocol handler. Result codes noErr No error lapProtErr Error detaching protocol type æKY PWriteLAP æFc AppleTalk.h æT Function æD pascal OSErr PWriteLAP(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PWriteLAP((MPPPBPtr) thePBptr,(Boolean) async); æRI II-307, V-513 æC WriteLAP function Parameter block -> 26 csCode word ;always writeLAP -> 30 wdsPointer pointer ;write data structure WriteLAP sends a frame to another node. The frame data and destination of the frame are described by the write data structure pointed to by wdsPointer. The first two data bytes of an ALAP frame sent to another computer using the AppleTalk Manager must indicate the length of the frame in bytes. The ALAP protocol type byte must be in the range 1 to 127. Result codes noErr No error excessCollsns No CTS received after 32 RTS's ddpLengthErr Packet length exceeds maximum lapProtErr Invalid ALAP protocol type æKY POpenSkt æFc AppleTalk.h æT Function æD pascal OSErr POpenSkt(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = POpenSkt((MPPPBPtr) thePBptr,(Boolean) async); æRI II-311, V-513 æC OpenSkt function Parameter block -> 26 csCode word ;always openSkt <-> 28 socket byte ;socket number -> 30 listener pointer ;socket listener OpenSkt adds a socket and its socket listener to the socket table. If the socket parameter is nonzero, it must be in the range 64 to 127, and it specifies the socket's number; if socket is 0, OpenSkt opens a socket with a socket number in the range 128 to 254, and returns it in the socket parameter. Listener contains a pointer to the socket listener. OpenSkt will return ddpSktErr if you pass the number of an already opened socket, if you pass a socket number greater than 127, or if the socket table is full (the socket table can hold a maximum of 12 sockets). Result codes noErr No error ddpSktErr Socket error æKY PCloseSkt æFc AppleTalk.h æT Function æD pascal OSErr PCloseSkt(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PCloseSkt((MPPPBPtr) thePBptr,(Boolean) async); æRI II-312,V513 æC CloseSkt function Parameter block -> 26 csCode word ;always closeSkt -> 28 socket byte ;socket number CloseSkt removes the entry of the specified socket from the socket table. If you pass a socket number of 0, or if you attempt to close a socket that isn't open, CloseSkt will return ddpSktErr. Result codes noErr No error ddpSktErr Socket error æKY PWriteDDP æFc AppleTalk.h æT Function æD pascal OSErr PWriteDDP(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PWriteDDP((MPPPBPtr) thePBptr,(Boolean) async); æRI II-312,V-513 æC WriteDDP function Parameter block -> 26 csCode word ;always writeDDP -> 28 socket byte ;socket number -> 29 checksumFlag byte ;checksum flag -> 30 wdsPointer pointer ;write data structure WriteDDP sends a datagram to another socket. WDSPointer points to a write data structure containing the datagram and the address of the destination socket. If checksumFlag is TRUE, WriteDDP will compute the checksum for all datagrams requiring long headers. Result codes noErr No error ddpLenErr Datagram length too big ddpSktErr Socket error noBridgeErr No bridge found æKY PRegisterName æFc AppleTalk.h æT Function æD pascal OSErr PRegisterName(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PRegisterName((MPPPBPtr) thePBptr,(Boolean) async); æRI II-322,V-513 æC RegisterName function Parameter block -> 26 csCode word ;always registerName -> 28 interval byte ;retry interval <-> 29 count byte ;retry count -> 30 ntQElPtr pointer ;names table element pointer -> 34 verifyFlag byte ;set if verify needed RegisterName adds the name and address of an entity to the node's names table. NTQElPtr points to a names table entry containing the entity's name and internet address (in the form shown in Figure 13 above). Meta-characters aren't allowed in the object and type fields of the entity name; the zone field, however, must contain the meta-character "*". If verifyFlag is TRUE, RegisterName checks on the network to see if the name is already in use, and returns a result code of nbpDuplicate if so. Interval and count contain the retry interval in eight-tick units and the retry count. When a retry is made, the count field is modified. Warning: The names table entry passed to RegisterName remains the property of NBP until removed from the names table. Don't attempt to remove or modify it. If you've allocated memory using a NewHandle call, you must lock it as long as the name is registered. Warning: VerifyFlag should normally be set before calling RegisterName. Result codes noErr No error nbpDuplicate Duplicate name already exists nbpNISErr Error opening names information socket æKY PLookupName æFc AppleTalk.h æT Function æD pascal OSErr PLookupName(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PLookupName((MPPPBPtr) thePBptr,(Boolean) async); æRI II-323,V-513 æC LookupName function Parameter block -> 26 csCode word ;always lookupName -> 28 interval byte ;retry interval <-> 29 count byte ;retry count -> 30 entityPtr pointer ;pointer to entity name -> 34 retBuffPtr pointer ;pointer to buffer -> 38 retBuffSize word ;buffer size in bytes -> 40 maxToGet word ;matches to get <-> 42 numGotten word ;matches found LookupName returns the addresses of all entities with a specified name. EntityPtr points to the entity's name (in the form shown in Figure 13 above). Meta- characters are allowed in the entity name. RetBuffPtr and retBuffSize contain the location and size of an area of memory in which the tuples describing the entity names and their corresponding addresses should be returned. MaxToGet indicates the maximum number of matching names to find addresses for; the actual number of addresses found is returned in numGotten. Interval and count contain the retry interval and the retry count. LookupName completes when either the number of matches is equal to or greater than maxToGet, or the retry count has been exceeded. The count field is decremented for each retransmission. Note: NumGotten is first set to 0 and then incremented with each match found. You can test the value in this field, and can start examining the received addresses in the buffer while the lookup continues. Result codes noErr No error nbpBuffOvr Buffer overflow æKY PConfirmName æFc AppleTalk.h æT Function æD pascal OSErr PConfirmName(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PConfirmName((MPPPBPtr) thePBptr,(Boolean) async); æRI II-323,V-513 æC ConfirmName function Parameter block -> 26 csCode word ;always confirmName -> 28 interval byte ;retry interval <-> 29 count byte ;retry count -> 30 entityPtr pointer ;pointer to entity name -> 34 confirmAddr pointer ;entity address <- 38 newSocket byte ;socket number ConfirmName confirms that an entity known by name and address still exists (is still entered in the names directory). EntityPtr points to the entity's name (in the form shown in Figure 13 above). ConfirmAddr specifies the address to confirmed. No meta-characters are allowed in the entity name. Interval and count contain the retry interval and the retry count. The socket number of the entity is returned in newSocket. ConfirmName is more efficient than LookupName in terms of network traffic. Result codes noErr No error nbpConfDiff Name confirmed for different socket nbpNoConfirm Name not confirmed æKY PRemoveName æFc AppleTalk.h æT Function æD pascal OSErr PRemoveName(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PRemoveName((MPPPBPtr) thePBptr,(Boolean) async); æRI II-324,V-513 æC RemoveName function Parameter block -> 26 csCode word ;always removeName -> 30 entityPtr pointer ;pointer to entity name RemoveName removes an entity name from the names table of the given entity's node. Result codes noErr No error nbpNotFound Name not found æKY PSetSelfSend æFc AppleTalk.h æT Function æD pascal OSErr PSetSelfSend(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PSetSelfSend((MPPPBPtr) thePBptr,(Boolean) async); æRI V-516 æC _______________________________________________________________________________ »SENDING PACKETS TO ONE’S OWN NODE _______________________________________________________________________________ Upon opening, the ability to send a packet to one’s own node (intranode delivery) is disabled. This feature of the AppleTalk Manager can be manipulated through the SetSelfSend function. Once enabled, it is possible, at all levels, to send packets to entities within one’s own node. An example of where this might be desirable is an application sending data to a print spooler that is actually running in the background on the same node. Enabling (or disabling) this feature affects the entire node and should be performed with care. For instance, a desk accessory may not expect to receive names from within its own node as a response to an NBP look-up; enabling this feature from an application could break the desk accessory. All future programs should be written with this feature in mind. FUNCTION PSetSelfSend (thePBptr: MPPPBPtr; async: BOOLEAN) : OSErr; Parameter Block --> 26 csCode word Always PSetSelfSend --> 28 newSelfFlag byte New SelfSend flag <-- 29 oldSelfFlag byte Old SelfSend flag PSetSelfSend enables or disables the intranode delivery feature of the AppleTalk Manager. If newSelfFlag is nonzero, the feature will be enabled; otherwise it will be disabled. The previous value of the flag will be returned in oldSelfFlag. Result Codes noErr No error æKY PKillNBP æFc AppleTalk.h æT Function æD pascal OSErr PKillNBP(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PKillNBP((MPPPBPtr) thePBptr,(Boolean) async); æRI V-518 æC _______________________________________________________________________________ »NAME BINDING PROTOCOL CHANGES _______________________________________________________________________________ Changes to the Name Binding Protocol include supporting multiple concurrent requests and a means for aborting an active request. »Multiple Concurrent NBP Requests NBP now supports multiple concurrent active requests. Specifically, a number of LookupNames, RegisterNames and ConfirmNames can all be active concurrently. The maximum number of concurrent requests is machine dependent; if it is exceeded the error tooManyReqs will be returned. Active requests can be aborted by the PKillNBP call. »KillNBP function FUNCTION PKillNBP (thePBptr: ATPPBPtr; async: BOOLEAN) : OSErr; •••Refer to Technical Note #199:••• Parameter block --> 26 csCode word Always PKillNBP --> 28 aKillQEl pointer Pointer to queue element PKillNBP is used to abort an outstanding LookupName, RegisterName or ConfirmName request. To abort one of these calls, place a pointer to the queue element of the call to abort in a KillQEl and issue the PKillNBP call. The call will be completed with a ReqAborted error. Result Codes noErr No error cbNotFound aKillQEl does not point to a valid NBP queue element æKY PGetAppleTalkInfo æFc AppleTalk.h æT Function æD pascal OSErr PGetAppleTalkInfo(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PGetAppleTalkInfo((MPPPBPtr) thePBptr,(Boolean) async); æRI VI æC You can use the PGetAppleTalkInfo function to obtain information about the .MPP driver. In addition to the node ID and other information pointed to by the ABusVars global variable (discussed in the AppleTalk Manager chapter of Volume II), the PGetAppleTalkInfo function returns • a pointer to the .MPP driver’s device control entry data structure (DCE) • configuration flags, which indicate the status of certain conditions that are set at startup • a value (the selfSend flag) that indicates whether the node can send packets to itself • the network number range for the network to which the node is attached • the 8-bit node ID and 16-bit network number of the node • the 8-bit node ID and 16-bit network number of the last router from which the node has heard • the maximum capacities of the .MPP driver—such as the maximum number of protocol handlers and the maximum number of static sockets allowed by this driver • a pointer to the registered names queue • the node address of the node on the underlying data link (for example, the Ethernet hardware address) • the node’s zone name The data link address (for example, the Ethernet hardware address) and the zone name are returned only for extended networks; that is, network types that allow more than one network per cable. You must allocate memory for and provide pointers to the data buffers into which the PGetAppleTalkInfo function returns the data link address and zone name. You use the laLength parameter to specify the length of the data link address you want returned; the function returns the actual length of the data in the laLength parameter and returns the data in the buffer you provide. Note: Always use the PGetAppleTalkInfo function to obtain information about the .MPP driver. You can no longer rely on the validity of the global variables described in the AppleTalk chapter of Inside Macintosh, Volume II. FUNCTION PGetAppleTalkInfo (thePBptr: MPPPBPtr; async: BOOLEAN) : OSErr; Parameter block ¨ 16 ioResult word result code Æ 26 csCode word always PGetAppleTalkInfo Æ 28 version word version of function ¨ 30 varsPtr pointer pointer to MPP globals ¨ 34 dcePtr pointer pointer to DCE for .MPP ¨ 38 portID word port number ¨ 40 configuration long configuration flags ¨ 44 selfSend word nonzero if self-send is enabled ¨ 46 netLo word low value of the network range ¨ 48 netHi word high value of the network range ¨ 50 ourAddr long local 24-bit AppleTalk address ¨ 54 routerAddr long 24-bit address of router ¨ 58 numOfPHs word max number of protocol handlers ¨ 60 numOfSkts word max number of static sockets ¨ 62 numNBPEs word max concurrent NBP requests ¨ 64 ntQueue pointer pointer to registered name queue ´ 68 laLength word length in bytes of data link address (extended networks only) Æ 70 linkAddr pointer pointer to data link address buffer (extended networks only) Æ 74 zoneName pointer pointer to zone name buffer The PGetAppleTalkInfo function returns information about the .MPP driver. If the node on which your program is running happens also to be running AppleTalk Internet Router software in the background, there may be more than one set of .MPP global variables in RAM. To make sure you are obtaining information about the .MPP driver that handles application software, always use the PGetAppleTalkInfo function rather than the Device Manager’s PBControl function. If you are using assembly language, or want to use the PBControl function, you must use a device driver reference number of –10 for the .MPP driver. Parameters ioResult The result of the function. When you execute the function asynchronously, the function sets this parameter to 1 and returns a function result of noErr as soon as the function begins execution. When the function completes execution, it sets the ioResult parameter to the actual result code. csCode Routine selector, automatically set by the MPW interface. Always equal to PGetAppleTalkInfo for this function. version The version number of the PGetAppleTalkInfo function you are calling. For version number 53 of the .MPP driver, this number is always 1. varsPtr A pointer to the MPP global variables. The MPP global variables are discussed in “Protocol Handlers and Socket Listeners” in Chapter 10 of Volume II. dcePtr A pointer to the device control entry (DCE) data structure for the .MPP driver. The DCE is described in the Device Manager chapters of Volumes II and V. portID The port number for the .MPP driver. The port number is always 0 unless you are requesting information for an .MPP driver being used by a router. configuration A 32-bit long word of configuration flags. The following flags are currently defined: Bit Flag Description 31 SrvAdrBit TRUE (1) if the routine that opened the .MPP driver requested a server node number. Server node numbers are described in the AppleTalk Manager of Volume V. This flag indicates only that the server-node number was requested, not that it was returned. Some AppleTalk devices, such as EtherTalk, do not honor a request for a server-node number. 30 RouterBit TRUE (1) if an AppleTalk Internet Router was loaded at system startup (that is, there's a router operating on the same node as your application). A router can be loaded but not active. 15 ExtendedBit TRUE (1) if the node is on an extended network. 7 BadZoneHintBit TRUE (1) if the zone name of the node you are on was not the same as the zone name stored in parameter RAM (sometimes referred to as the zone name hint) when the .MPP driver was opened. If the zone name hint is invalid, then the AppleTalk Manager uses the default zone for the network. 6 OneZoneBit TRUE (1) if only one zone is assigned to your extended network or if you are not on an extended network. selfSend This parameter is nonzero if the ability of a node to send packets to itself is enabled. Use the PSetSelfSend function, described in the AppleTalk Manager chapter of Volume V, to enable or disable this feature. netLo The low value of the range of network numbers on the local cable. Only extended networks can have a range of network numbers. For a nonextended network, this parameter returns the network number. netHi The high value of the range of network numbers on the local cable. Only extended networks can have a range of network numbers. For a nonextended network, this parameter returns the network number. ourAddr The 24-bit AppleTalk network address of the node you are on. The least significant byte of the longword is the node ID. The middle 16 bits are the network number. The most significant byte of the longword is reserved for use by Apple Computer, Inc. routerAddr The 24-bit AppleTalk network address of the last router from which your node heard traffic. The least significant byte of the longword is the node ID. The middle 16 bits are the network number. The most significant byte of the longword is reserved for use by Apple Computer, Inc. You should always use this address when you want to communicate with a router. numOfPHs The maximum number of protocol handlers that this .MPP driver allows. numOfSkts The maximum number of statically assigned sockets that this .MPP driver allows. Statically assigned sockets are described in Inside AppleTalk. numNBPEs The maximum number of concurrent requests to NBP that this .MPP driver allows. ntQueue A pointer to the first entry in the names table for the local node. You can use NBP routines to look up and register names in the names table. The names table is described in “Name-Binding Protocol” in Chapter 10 of Volume II. laLength When you call the PGetAppleTalkInfo function on a node on an extended network, you use this parameter to specify the number of bytes of the data link address the function should place in the buffer pointed to by the LinkAddr parameter. If you request more bytes than the total number of bytes in the address, then the function returns in the laLength parameter the actual number of bytes it placed in the buffer. If the address is longer than the size of the buffer, then the PGetAppleTalkInfo function fills the buffer and returns in the laLength parameter the actual length of the address, not the number of bytes returned. The function does not return an error when the buffer is too large or too small for the address. linkAddr A pointer to a buffer for the data link address returned for extended networks only. You use the laLength parameter to specify the number of bytes of the address that you want placed in this buffer. You must allocate a buffer large enough to hold the number of bytes you specify. Speficy NIL for this parameter if you do not want the function to provide a data-link address. zoneName A pointer to a buffer into which the PGetAppleTalkInfo function places the local node’s zone name. You must allocate a buffer of at least 33 bytes to hold this data, or specify NIL for the ZoneName parameter if you do not want to obtain the zone name. This field is returned only if the node is on an extended network. Result codes noErr 0 no error æKY PATalkClosePrep æFc AppleTalk.h æT Function æD pascal OSErr PATalkClosePrep(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PATalkClosePrep((MPPPBPtr) thePBptr,(Boolean) async); æRI VI æC Whereas it is unlikely that opening the .MPP driver will adversely affect another program, an application should never close the .MPP driver, because another program might be using it. Under certain circumstances, however, the system might close the .MPP driver, provided no application objects. The system uses the .MPP driver’s PATalkClosePrep function to inform each routine in the AppleTalk Transition Queue that it intends to close the .MPP driver, giving each routine in the queue the opportunity to deny permission to do so. The system provides a pointer to a 255-byte buffer when it calls the PATalkClosePrep function. If any routine in the AppleTalk Transition Queue denies permission to close the .MPP driver, it places a name in the buffer and returns control to the AppleTalk Manager. The name that the routine places in the buffer should be the name of the application that placed the entry in the queue. The PATalkClosePrep function then calls each routine in the AppleTalk Transition Queue a second time to inform it that the request to close the .MPP driver has been canceled. If any routine in the AppleTalk Transition Queue denies permission to close the .MPP driver, the PATalkClosePrep function returns the result code closeErr. If any routine denies permission to close the .MPP driver, the system displays a dialog box informing the user that another application is using the .MPP driver, and showing the name that the AppleTalk Transition Queue routine placed in the buffer. The dialog box gives the user the option of canceling the request to close AppleTalk, or of closing AppleTalk anyway. Note: If the user chooses to close AppleTalk despite the fact that an application is using it, the system calls the MPPClose function. AppleTalk calls each application in the AppleTalk Transition Queue again, this time informing it that AppleTalk is about to close. In this case, your AppleTalk Transition Queue routine must prepare for the imminent closing of AppleTalk; it cannot deny permission to the MPPClose function. FUNCTION PATalkClosePrep (thePBptr: MPPPBPtr; async: BOOLEAN) : OSErr; Parameter block Æ 26 csCode word always PATalkClosePrep Æ appName pointer buffer for name of application that denies request The PATalkClosePrep function calls each routine listed in the AppleTalk Transition Queue to request permission to close the .MPP driver. The routine that calls the PATalkClosePrep function must allocate a 255-byte buffer and provide a pointer to it in the appName parameter. If a routine in the AppleTalk Transition Queue denies permission to close the .MPP driver, that routine places a name in the buffer pointed to by the appName parameter, and the AppleTalk Manager calls each routine in the AppleTalk Transition Queue a second time to inform it that the request to close the .MPP driver has been canceled. The PATalkClosePrep function then returns the result code closeErr, indicating that the calling routine may not close the .MPP driver. The csCode parameter is a routine selector; it is always equal to PATalkClosePrep for this function. Result codes noErr 0 no error closeErr –24 permission to close .MPP driver was denied æKY PCancelATalkClosePrep æFc AppleTalk.h æT Function æD pascal OSErr PCancelATalkClosePrep(MPPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = PCancelATalkClosePrep((MPPPBPtr) thePBptr,(Boolean) async); æRI VI æC The system can use the PCancelATClosePrep function to undo the effects of the PATalkClosePrep function. The system uses this function, for example, if some condition prevents it from closing the .MPP driver even though each routine listed in the AppleTalk Transition Queue gave permission to close it. When the system calls the PCancelATClosePrep function, the AppleTalk Manager calls each routine in the AppleTalk Transition Queue to inform it that the request to close the .MPP driver has been canceled. FUNCTION PCancelATClosePrep (thePBptr: MPPPBPtr; async: BOOLEAN) : OSErr; Parameter block Æ 26 csCode word always PCancelATClosePrep The PCancelATClosePrep function undoes the effects of the PATalkClosePrep function. The PCancelATClosePrep function calls each routine in the AppleTalk Transition Queue to inform it that the request to close the .MPP driver has been canceled. The operating system uses this function, for example, if some condition prevents it from closing the .MPP driver even though each routine listed in the AppleTalk Transition Queue gave permission to close it. The csCode parameter is a routine selector, always equal to PCancelATClosePrep for this function. Result codes noErr 0 no error æKY POpenATPSkt æFc AppleTalk.h æT Function æD pascal OSErr POpenATPSkt(ATPPBPtr thePBptr,Boolean async); æDT OSErr myVariable = POpenATPSkt((ATPPBPtr) thePBptr,(Boolean) async); æRI II-315,V-513 æC OpenATPSkt function Parameter block -> 26 csCode word ;always openATPSkt <-> 28 atpSocket byte ;socket number -> 30 addrBlock long word ;socket request specification OpenATPSkt opens a socket for the purpose of receiving requests. ATPSocket contains the socket number of the socket to open. If it's 0, a number is dynamically assigned and returned in atpSocket. AddrBlock contains a specification of the socket addresses from which requests will be accepted. A 0 in the network number, node ID, or socket number field of addrBlock means that requests will be accepted from every network, node, or socket, respectively. Result codes noErr No error tooManySkts Too many responding sockets noDataArea Too many outstanding ATP calls æKY PCloseATPSkt æFc AppleTalk.h æT Function æD pascal OSErr PCloseATPSkt(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PCloseATPSkt((ATPPBPtr) thePBPtr,(Boolean) async); æRI II-316,V-513 æC CloseATPSkt function Parameter block -> 26 csCode word ;always closeATPSkt -> 28 atpSocket byte ;socket number CloseATPSkt closes the socket whose number is specified by atpSocket, for the purpose of receiving requests. Result codes noErr No error æKY PSendRequest æFc AppleTalk.h æT Function æD pascal OSErr PSendRequest(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PSendRequest((ATPPBPtr) thePBPtr,(Boolean) async); æRI II-316,V-513 æC SendRequest function Parameter block -> 18 userData long word ;user bytes <- 22 reqTID word ;transaction ID used in request -> 26 csCode word ;always sendRequest <- 28 currBitMap byte ;bit map <-> 29 atpFlags byte ;control information -> 30 addrBlock long word ;destination socket address -> 34 reqLength word ;request size in bytes -> 36 reqPointer pointer ;pointer to request data -> 40 bdsPointer pointer ;pointer to response BDS -> 44 numOfBuffs byte ;number of responses expected -> 45 timeOutVal byte ;timeout interval <- 46 numOfResps byte ;number of responses received <-> 47 retryCount byte ;number of retries SendRequest sends a request to another socket and waits for a response. UserData contains the four user bytes. AddrBlock indicates the socket to which the request should be sent. ReqLength and reqPointer contain the size and location of the request to send. BDSPointer points to a response BDS where the responses are to be returned; numOfBuffs indicates the number of responses requested. The number of responses received is returned in numOfResps. If a nonzero value is returned in numOfResps, you can examine currBitMap to determine which packets of the transaction were actually received and to detect pieces for higher-level recovery, if desired. TimeOutVal indicates the number of seconds that SendRequest should wait for a response before resending the request. RetryCount indicates the maximum number of retries SendRequest should attempt. The end-of-message flag of atpFlags will be set if the EOM bit is set in the last packet received in a valid response sequence. The exactly-once flag should be set if you want the request to be part of an exactly-once transaction. To cancel a SendRequest call, you need the transaction ID; it's returned in reqTID. You can examine reqTID before the completion of the call, but its contents are valid only after the tidValid bit of atpFlags has been set. SendRequest completes when either an entire response is received or the retry count is exceeded. Note: The value provided in retryCount will be modified during SendRequest if any retries are made. This field is used to monitor the number of retries; for each retry, it's decremented by 1. Result codes noErr No error reqFailed Retry count exceeded tooManyReqs Too many concurrent requests noDataArea Too many outstanding ATP calls reqAborted Request canceled by user æKY PGetRequest æFc AppleTalk.h æT Function æD pascal OSErr PGetRequest(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PGetRequest((ATPPBPtr) thePBPtr,(Boolean) async); æRI II-317,V-513 æC GetRequest function Parameter block <- 18 userData long word ;user bytes -> 26 csCode word ;always getRequest -> 28 atpSocket byte ;socket number <- 29 atpFlags byte ;control information <- 30 addrBlock long word ;source of request <-> 34 reqLength word ;request buffer size -> 36 reqPointer pointer ;pointer to request buffer <- 44 bitMap byte ;bit map <- 46 transID word ;transaction ID GetRequest sets up the mechanism to receive a request sent by a SendRequest call. UserData returns the four user bytes from the request. ATPSocket contains the socket number of the socket that should listen for a request. The internet address of the socket from which the request was sent is returned in addrBlock. ReqLength and reqPointer indicate the size (in bytes) and location of a buffer to store the incoming request. The actual size of the request is returned in reqLength. The transaction bit map and transaction ID will be returned in bitMap and transID. The exactly-once flag in atpFlags will be set if the request is part of an exactly-once transaction. GetRequest completes when a request is received. Result codes noErr No error badATPSkt Bad responding socket æKY PSendResponse æFc AppleTalk.h æT Function æD pascal OSErr PSendResponse(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PSendResponse((ATPPBPtr) thePBPtr,(Boolean) async); æRI II-317,V-513 æC SendResponse function Parameter block <- 18 userData long word ;user bytes from TRel <- 22 reqTID word ;transaction ID used in request -> 26 csCode word ;always sendResponse -> 28 atpSocket byte ;socket number -> 29 atpFlags byte ;control information -> 30 addrBlock long word ;response destination -> 40 bdsPointer pointer ;pointer to response BDS -> 44 numOfBuffs byte ;number of response packets being sent -> 45 bdsSize byte ;BDS size in elements -> 46 transID word ;transaction ID SendResponse sends a response to a socket. If the response was part of an exactly- once transaction, userData will contain the user bytes from the TRel packet. ATPSocket contains the socket number from which the response should be sent. The end-of-message flag in atpFlags should be set if the response contains the final packet in a transaction composed of a group of packets and the number of responses is less than requested. AddrBlock indicates the address of the socket to which the response should be sent. BDSPointer points to a response BDS containing room for the maximum number of responses to be sent; bdsSize contains this maximum number. NumOfBuffs contains the number of response packets to be sent in this call; you may wish to make AddResponse calls to complete the response. TransID indicates the transaction ID of the associated request. During exactly-once transactions, SendResponse doesn't complete until either a TRel packet is received from the socket that made the request, or the retry count is exceeded. Result codes noErr No error badATPSkt Bad responding socket noRelErr No release received noDataArea Too many outstanding ATP calls badBuffNum Sequence number out of range æKY PAddResponse æFc AppleTalk.h æT Function æD pascal OSErr PAddResponse(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PAddResponse((ATPPBPtr) thePBPtr,(Boolean) async); æRI II-318,V-513 æC AddResponse function Parameter block -> 18 userData long word ;user bytes -> 26 csCode word ;always addResponse -> 28 atpSocket byte ;socket number -> 29 atpFlags byte ;control information -> 30 addrBlock long word ;response destination -> 34 reqLength word ;response size -> 36 reqPointer pointer ;pointer to response -> 44 rspNum byte ;sequence number -> 46 transID word ;transaction ID AddResponse sends an additional response packet to a socket that has already been sent the initial part of a response via SendResponse. UserData contains the four user bytes. ATPSocket contains the socket number from which the response should be sent. The end-of-message flag in atpFlags should be set if this response packet is the final packet in a transaction composed of a group of packets and the number of responses is less than requested. AddrBlock indicates the socket to which the response should be sent. ReqLength and reqPointer contain the size (in bytes) and location of the response to send; rspNum indicates the sequence number of the response (in the range 0 to 7). TransID must contain the transaction ID. Warning: If the transaction is part of an exactly-once transaction, the buffer used in the AddResponse call must not be altered or released until the corresponding SendResponse call has completed. Result codes noErr No error badATPSkt Bad responding socket noSendResp AddResponse issued before SendResponse badBuffNum Sequence number out of range noDataArea Too many outstanding ATP calls æKY PRelTCB æFc AppleTalk.h æT Function æD pascal OSErr PRelTCB(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PRelTCB((ATPPBPtr) thePBPtr,(Boolean) async); æRI II-319,V-513 æC RelTCB function Parameter block -> 26 csCode word ;always relTCB -> 30 addrBlock long word ;destination of request -> 46 transID word ;transaction ID of request RelTCB dequeues the specified SendRequest call and returns the result code reqAborted for the aborted call. The transaction ID can be obtained from the reqTID field of the SendRequest queue entry; see the description of SendRequest for details. Result codes noErr No error cbNotFound ATP control block not found noDataArea Too many outstanding ATP calls æKY PRelRspCB æFc AppleTalk.h æT Function æD pascal OSErr PRelRspCB(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PRelRspCB((ATPPBPtr) thePBPtr,(Boolean) async); æRI II-319,V-514 æC RelRspCB function Parameter block -> 26 csCode word ;always relRspCB -> 28 atpSocket byte ;socket number that request was received on -> 30 addrBlock long word ;source of request -> 46 transID word ;transaction ID of request In an exactly-once transaction, RelRspCB cancels the specified SendResponse, without waiting for the release timer to expire or a TRel packet to be received. No error is returned for the SendResponse call. Whan called to cancel a transaction that isn't using exactly-once service, RelRspCB returns cbNotFound. The transaction ID can be obtained from the reqTID field of the SendResponse queue entry; see the description of SendResponse for details. Result codes noErr No error cbNotFound ATP control block not found æKY PNSendRequest æFc AppleTalk.h æT Function æD pascal OSErr PNSendRequest(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PNSendRequest((ATPPBPtr) thePBPtr,(Boolean) async); æRI V-516 æC »Sending an ATP Request Through a Specified Socket ATP requests can now be sent through client-specified sockets. ATP previously would open a dynamic socket, send the request through it, and close the socket when the request was completed. The client can now choose to send a request through an already-opened socket; this also allows more than one request to be sent per socket. A new call, PNSendRequest, has been added for this purpose. The function of the old SendRequest call itself remains unchanged. FUNCTION PNSendRequest (thePBptr: ATPBPtr; async: BOOLEAN) : OSErr; Parameter block --> 18 userData longword User bytes <-- 22 reqTID word Transaction ID used in request --> 26 csCode word Always sendRequest <-> 28 atpSocket byte Socket to send request on or current bitmap <-> 29 atpFlags byte Control information --> 30 addrBlock longword Destination socket address --> 34 reqLength word Request size in bytes --> 36 reqPointer pointer Pointer to request data --> 40 bdsPointer pointer Pointer to response BDS --> 44 numOfBuffs byte Number of responses expected --> 45 timeOutVal byte Timeout interval <-- 46 numOf Resps byte Number of responses received <-> 47 retryCount byte Number of retries <-- 48 intBuff word Used internally The PNSendRequest call is functionally equivalent to the SendRequest call, however PNSendRequest allows you to specify, in the atpSocket field, the socket through which the request is to be sent. This socket must have been previously opened through an OpenATPSkt request (otherwise a badATPSkt error will be returned). Note that PNSendRequest requires two additional bytes of memory at the end of the parameter block, immediately following the retryCount. These bytes are for the internal use of the AppleTalk Manager and should not be modified while the PNSendRequest call is active. There is a machine-dependent limit as to the number of concurrent PNSendRequests that can be active on a given socket. If this limit is exceeded, the error tooManyReqs is returned. One additional difference between SendRequest and PNSendRequest is that a PNSendRequest can only be aborted by a PKillSendReq call (see below), whereas a SendRequest can be aborted by either a RelTCB or KillSendReq call. Result Codes noErr No error reqFailed Retry count exceeded tooManyReqs Too many concurrent requests noDataArea Too many outstanding ATP calls reqAborted Request cancelled by user æKY PKillSendReq æFc AppleTalk.h æT Function æD pascal OSErr PKillSendReq(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PKillSendReq((ATPPBPtr) thePBPtr,(Boolean) async); æRI V-517 æC »Aborting ATP SendRequests The RelTCB call is still supported, but only for aborting SendRequests. To abort PNSendRequests, a new call, PKillSendReq, has been added. This call will abort both SendRequests and PNSendRequests. PKillSendReq’s only argument is the queue element pointer of the request to be aborted. The queue element pointer is passed at the offset of the PKillSendReq queue element specified by aKillQE1. FUNCTION PKillSendReq (thePBptr: ATPPBPtr; async: BOOLEAN) : OSErr; Parameter block --> 26 csCode word Always PKillSendReq --> 44 aKillQEl pointer Pointer to queue element PKillSendReq is functionally equivalent to RelTCB, except that it takes different arguments and will abort both SendRequests and PNSendRequests. To abort one of these calls, place a pointer to the queue element of the call to abort in aKillQEl and issue the PKillSendReq call. Result Codes noErr No error cbNotFound aKillQEl does not point to a SendReq or NSendReq queue element æKY PKillGetReq æFc AppleTalk.h æT Function æD pascal OSErr PKillGetReq(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PKillGetReq((ATPPBPtr) thePBPtr,(Boolean) async); æRI V-518 æC »Aborting ATP GetRequests ATP GetRequests can now be aborted through the PKillGetReq call. This call looks and works just like the PKillSendReq call, and is used to abort a specific GetRequest call. Previously it was necessary to close the socket to abort all GetRequest calls on the socket. FUNCTION PKillGetReq (thePBptr: ATPPBPtr; async: BOOLEAN) : OSErr; Parameter block --> 26 csCode word Always PKillGetReq --> 44 aKillQEl pointer Pointer to queue element PKillGetReq will abort a specific outstanding GetRequest call (as opposed to closing the socket, which aborts all outstanding GetRequests on that socket). The call will be completed with a reqAborted error. To abort a GetRequest, place a pointer to the queue element of the call to abort in aKillQEl and issue the PKillGetReq call. Result Codes noErr No error cbNotFound aKillQEl does not point to a GetReq queue element æKY PKillAllGetReq æFc AppleTalk.h æT Function æD pascal OSErr PKillAllGetReq(ATPPBPtr thePBPtr,Boolean async); æDT OSErr myVariable = PKillAllGetReq((ATPPBPtr) thePBPtr,(Boolean) async); æRI V-518 æC »Aborting ATP GetRequests ATP GetRequests can now be aborted through the PKillGetReq call. This call looks and works just like the PKillSendReq call, and is used to abort a specific GetRequest call. Previously it was necessary to close the socket to abort all GetRequest calls on the socket. FUNCTION PKillGetReq (thePBptr: ATPPBPtr; async: BOOLEAN) : OSErr; Parameter block --> 26 csCode word Always PKillGetReq --> 44 aKillQEl pointer Pointer to queue element PKillGetReq will abort a specific outstanding GetRequest call (as opposed to closing the socket, which aborts all outstanding GetRequests on that socket). The call will be completed with a reqAborted error. To abort a GetRequest, place a pointer to the queue element of the call to abort in aKillQEl and issue the PKillGetReq call. Result Codes noErr No error cbNotFound aKillQEl does not point to a GetReq queue element æKY BuildLAPwds æFc AppleTalk.h æT Function æD pascal void BuildLAPwds(Ptr wdsPtr,Ptr dataPtr,short destHost,short prototype, short frameLen); æDT BuildLAPwds((Ptr) wdsPtr,(Ptr) dataPtr,(short) destHost,(short) prototype,() short frameLen); æRI V-514 æC This routine builds a single-frame write data structure LAP WDS for use with the PWriteLAP call. Given a buffer of length frameLen pointed to by dataPtr, it fills in the WDS pointed to by wdsPtr and sets the destination node and protocol type as indicated by destHost and protoType, respectively. The WDS indicated must contain at least two elements. æKY BuildDDPwds æFc AppleTalk.h æT Function æD pascal void BuildDDPwds(Ptr wdsPtr,Ptr headerPtr,Ptr dataPtr,const AddrBlock netAddr, short ddpType,short dataLen); æDT BuildDDPwds((Ptr) wdsPtr,(Ptr) headerPtr,(Ptr) dataPtr,(const AddrBlock) netAddr,() short ddpType,(short) dataLen); æRI V-514 æC This routine builds a single-frame write data structure DDP WDS, for use with the PWriteDDP call. Given a header buffer of at least 17 bytes pointed to by headerPtr and a data buffer of length dataLen pointed to by dataPtr, it fills in the WDS pointed to by wdsPtr, and sets the destination address and protocol type as indicated by destaddress and DDPtype, respectively. The WDS indicated must contain at least 3 elements. æKY NBPSetEntity æFc AppleTalk.h æT Function æD pascal void NBPSetEntity(Ptr buffer,Ptr nbpObject,Ptr nbpType,Ptr nbpZone); æDT NBPSetEntity((Ptr) buffer,(Ptr) nbpObject,(Ptr) nbpType,(Ptr) nbpZone); æRI V-514 æC This routine builds an NBP entity structure, for use with the PLookupNBP and PConfirmName calls. Given a buffer of at least the size of the EntityName data structure (99 bytes) pointed to by buffer, this routine sets the indicated object, type, and zone in that buffer. æKY NBPSetNTE æFc AppleTalk.h æT Function æD pascal void NBPSetNTE(Ptr ntePtr,Ptr nbpObject,Ptr nbpType,Ptr nbpZone, short socket); æDT NBPSetNTE((Ptr) ntePtr,(Ptr) nbpObject,(Ptr) nbpType,(Ptr) nbpZone,() short socket); æRI V-515 æC This routine builds an NBP names table entry, for use with the PRegisterName call. Given a names table entry of at least the size of the EntityName data structure plus nine bytes (108 bytes) pointed to by ntePtr, this routine sets the indicated object, type, zone, and socket in that names table entry. æKY GetBridgeAddress æFc AppleTalk.h æT Function æD pascal short GetBridgeAddress(void); æDT short myVariable = GetBridgeAddress()(void); æRT 132 æRI V-515, N132-2 æC This routine returns the current address of a bridge in the low byte, or zero if there is none. æKY BuildBDS æFc AppleTalk.h æT Function æD pascal short BuildBDS(Ptr buffPtr,Ptr bdsPtr,short buffSize); æDT short myVariable = BuildBDS((Ptr) buffPtr,(Ptr) bdsPtr,(short) buffSize); æRI V-515 æC This routine builds a BDS, for use with the ATP calls. Given a data buffer of length buffSize pointed to by buffPtr, it fills in the BDS pointed to by bdsPtr. The buffer will be broken up into pieces of maximum size (578 bytes). The user bytes in the BDS are not modified by this routine. This routine is provided only as a convenience; generally the caller will be able to build the BDS completely from Pascal without it. æKY MPPOpen æFc AppleTalk.h æT Function æD pascal OSErr MPPOpen(void); æDT OSErr myVariable = MPPOpen()(void); æMM æRT 224 æRI II-275 æC MPPOpen first checks whether the .MPP driver has already been loaded; if it has, MPPOpen does nothing and returns noErr. If MPP hasn’t been loaded, MPPOpen attempts to load it into the system heap. If it succeeds, it then initializes the driver’s variables and goes through the process of dynamically assigning a node ID to that Macintosh. On a Macintosh 512K or XL, it also loads the .ATP driver and NBP code into the system heap. If serial port B isn’t configured for AppleTalk, or is already in use, the .MPP driver isn’t loaded and an appropriate result code is returned. Result codes noErr No error portInUse Port B is already in use portNotCf Port B not configured for AppleTalk æKY MPPClose æFc AppleTalk.h æT Function æD pascal OSErr MPPClose(void); æDT OSErr myVariable = MPPClose()(void); æMM æRI II-275 æC MPPClose removes the .MPP driver, and any data structures associated with it, from memory. If the .ATP driver or NBP code were also installed, they’re removed as well. MPPClose also returns the use of port B to the Serial Driver. Warning: Since other co-resident programs may be using AppleTalk, it’s strongly recommended that you never use this call. MPPClose will completely disable AppleTalk; the only way to restore AppleTalk is to call MPPOpen again. æKY LAPOpenProtocol æFc AppleTalk.h æT Function æD pascal OSErr LAPOpenProtocol(ABByte theLAPType,Ptr protoPtr); æDT OSErr myVariable = LAPOpenProtocol((ABByte) theLAPType,(Ptr) protoPtr); æMM æRI II-277 æC LAPOpenProtocol adds the ALAP protocol type specified by theLAPType to the node’s protocol table. If you provide a pointer to a protocol handler in protoPtr, ALAP will send each frame with an ALAP protocol type of theLAPType to that protocol handler. If protoPtr is NIL, the default protocol handler will be used for receiving frames with an ALAP protocol type of theLAPType. In this case, to receive a frame you must call LAPRead to provide the default protocol handler with a buffer for placing the data. If, however, you’ve written your own protocol handler and protoPtr points to it, your protocol handler will have the responsibility for receiving the frame and it’s not necessary to call LAPRead. Result codes noErr No error lapProtErr Error attaching protocol type æKY LAPCloseProtocol æFc AppleTalk.h æT Function æD pascal OSErr LAPCloseProtocol(ABByte theLAPType); æDT OSErr myVariable = LAPCloseProtocol((ABByte) theLAPType); æMM æRI II-277 æC LAPCloseProtocol removes from the node’s protocol table the specified ALAP protocol type, as well as its protocol handler. Warning: Don’t close ALAP protocol type values 1 or 2. If you close these protocol types, DDP will be disabled; once disabled, the only way to restore DDP is to restart the system, or to close and then reopen AppleTalk. Result codes noErr No error lapProtErr Error detaching protocol type æKY LAPWrite æFc AppleTalk.h æT Function æD pascal OSErr LAPWrite(ATLAPRecHandle abRecord,Boolean async); æDT OSErr myVariable = LAPWrite((ATLAPRecHandle) abRecord,(Boolean) async); æMM æRI II-277 æC ABusRecord <-- abOpcode {always tLAPWrite} <-- abResult {result code} --> abUserReference {for your use} --> lapAddress.dstNodeID {destination node ID} --> lapAddress.lapProtType {ALAP protocol type} --> lapReqCount {length of frame data} --> lapDataPtr {pointer to frame data} LAPWrite sends a frame to another node. LAPReqCount and lapDataPtr specify the length and location of the data to send. The lapAddress.lapProtType field indicates the ALAP protocol type of the frame and the lapAddress.dstNodeID indicates the node ID of the node to which the frame should be sent. Note: The first two bytes of an ALAP frame’s data must contain the length in bytes of that data, including the length bytes themselves. Result codes noErr No error excessCollsns Unable to contact destination node; packet not sent ddpLenErr ALAP data length too big lapProtErr Invalid ALAP protocol type æKY LAPRead æFc AppleTalk.h æT Function æD pascal OSErr LAPRead(ATLAPRecHandle abRecord,Boolean async); æDT OSErr myVariable = LAPRead((ATLAPRecHandle) abRecord,(Boolean) async); æMM æRI II-278 æC ABusRecord <-- abOpcode {always tLAPRead} <-- abResult {result code} --> abUserReference {for your use} <-- lapAddress.dstNodeID {destination node ID} <-- lapAddress.srcNodeID {source node ID} --> lapAddress.lapProtType {ALAP protocol type} --> lapReqCount {buffer size in bytes} <-- lapActCount {number of frame data bytes actually received} --> lapDataPtr {pointer to buffer} LAPRead receives a frame from another node. LAPReqCount and lapDataPtr specify the size and location of the buffer that will receive the frame data. If the buffer isn’t large enough to hold all of the incoming frame data, the extra bytes will be discarded and buf2SmallErr will be returned. The number of bytes actually received is returned in lapActCount. Only frames with ALAP protocol type equal to lapAddress.lapProtType will be received. The node IDs of the frame’s source and destination nodes are returned in lapAddress.srcNodeID and lapAddress.dstNodeID. You can determine whether the packet was broadcast to you by examining the value of lapAddress.dstNodeID—if the packet was broadcast it’s equal to 255, otherwise it’s equal to your node ID. Note: You should issue LAPRead calls only for ALAP protocol types that were opened (via LAPOpenProtocol) to use the default protocol handler. Warning: If you close a protocol type for which there are still LAPRead calls pending, the calls will be canceled but the memory occupied by their ABusRecords will not be released. For this reason, before closing a protocol type, call LAPRdCancel to cancel any pending LAPRead calls associated with that protocol type. Result codes noErr No error buf2SmallErr Frame too large for buffer readQErr Invalid protocol type or protocol type not found in table æKY LAPRdCancel æFc AppleTalk.h æT Function æD pascal OSErr LAPRdCancel(ATLAPRecHandle abRecord); æDT OSErr myVariable = LAPRdCancel((ATLAPRecHandle) abRecord); æMM æRI II-279 æC Given the handle to the ABusRecord of a previously made LAPRead call, LAPRdCancel dequeues the LAPRead call, provided that a packet satisfying the LAPRead has not already arrived. LAPRdCancel returns noErr if the LAPRead call is successfully removed from the queue. If LAPRdCancel returns recNotFnd, check the abResult field to verify that the LAPRead has been completed and determine its outcome. Result codes noErr No error readQErr Invalid protocol type or protocol type not found in table recNotFnd ABRecord not found in queue »Example This example sends an ALAP packet synchronously and waits asynchronously for a response. Assume that both nodes are using a known protocol type (in this case, 73) to receive packets, and that the destination node has a node ID of 4. VAR myABRecord: ABRecHandle; myBuffer: PACKED ARRAY [0..599] OF CHAR; {buffer for both send and receive} myLAPType: Byte; errCode, index, dataLen: INTEGER; someText: Str255; async: BOOLEAN; BEGIN errCode := MPPOpen; IF errCode <> noErr THEN WRITELN('Error in opening AppleTalk') {Maybe serial port B isn't available for use by AppleTalk} ELSE BEGIN {Call Memory Manager to allocate ABusRecord} myABRecord := ABRecHandle(NewHandle(lapSize)); myLAPType := 73; {Enter myLAPType into protocol handler table and install default handler to } { service frames of that ALAP type. No packets of that ALAP type will be } { received until we call LAPRead.} errCode := LAPOpenProtocol(myLAPType, NIL); IF errCode <> noErr THEN WRITELN('Error while opening the protocol type') {Have we opened too many protocol types? Remember that DDP uses two of } { them.} ELSE BEGIN {Prepare data to be sent} someText := 'This data will be in the ALAP data area'; {The .MPP implementation requires that the first two bytes of the ALAP } { data field contain the length of the data, including the length bytes } { themselves.} dataLen := LENGTH(someText) + 2; buffer[0] := CHR(dataLen DIV 256); {high byte of data length} buffer[1] := CHR(dataLen MOD 256); {low byte of data length} FOR index := 1 TO dataLen - 2 DO {stuff buffer with packet data} buffer[index + 1] := someText[index]; async := FALSE; WITH myABRecord^^ DO {fill parameters in the ABusRecord} BEGIN lapAddress.lapProtType := myLAPType; lapAddress.dstNodeID := 4; lapReqCount := dataLen; lapDataPtr := @buffer; END; {Send the frame} errCode := LAPWrite(myABRecord, async); {In the case of a sync call, errCode and the abResult field of } { the myABRecord will contain the same result code. We can also } { reuse myABRecord, since we know whether the call has completed.} IF errCode <> noErr THEN WRITELN('Error while writing out the packet') {Maybe the receiving node wasn't on-line} ELSE BEGIN {We have sent out the packet and are now waiting for a response. We } { issue an async LAPRead call so that we don't “hang” waiting for a } { response that may not come.} async := TRUE; WITH myABRecord^^ DO BEGIN lapAddress.lapProtType := myLAPType; {ALAP type we want to receive } lapReqCount := 600; {our buffer is maximum size} lapDataPtr := @buffer; END; errCode := LAPRead(myABRecord, async); {wait for a packet} IF errCode <> noErr THEN WRITELN('Error while trying to queue up a LAPRead') {Was the protocol handler installed correctly?} ELSE BEGIN {We can either sit here in a loop and poll the abResult } { field or just exit our code and use the event } { mechanism to flag us when the packet arrives.} CheckForMyEvent; {your procedure for checking for a network event} errCode := LAPCloseProtocol(myLAPType); IF errCode <> noErr THEN WRITELN('Error while closing the protocol type'); END; END; END; END; END. æKY DDPOpenSocket æFc AppleTalk.h æT Function æD pascal OSErr DDPOpenSocket(short *theSocket,Ptr sktListener); æDT OSErr myVariable = DDPOpenSocket((short *) theSocket,(Ptr) sktListener); æMM æRI II-282 æC DDPOpenSocket adds a socket and its socket listener to the socket table. If theSocket is nonzero, it must be in the range 64 to 127, and it specifies the socket’s number; if theSocket is 0, DDPOpenSocket dynamically assigns a socket number in the range 128 to 254, and returns it in theSocket. SktListener contains a pointer to the socket listener; if it’s NIL, the default listener will be used. If you’re using the default socket listener, you must then call DDPRead to receive a datagram (in order to specify buffer space for the default socket listener). If, however, you’ve written your own socket listener and sktListener points to it, your listener will provide buffers for receiving datagrams and you shouldn’t use DDPRead calls. DDPOpenSocket will return ddpSktErr if you pass the number of an already opened socket, if you pass a socket number greater than 127, or if the socket table is full. Note: The range of static socket numbers 1 through 63 is reserved by Apple for internal use. Socket numbers 64 through 127 are available for unrestricted experimental use. Result codes noErr No error ddpSktErr Socket error æKY DDPCloseSocket æFc AppleTalk.h æT Function æD pascal OSErr DDPCloseSocket(short theSocket); æDT OSErr myVariable = DDPCloseSocket((short) theSocket); æMM æRI II-282 æC DDPCloseSocket removes the entry of the specified socket from the socket table and cancels all pending DDPRead calls that have been made for that socket. If you pass a socket number of 0, or if you attempt to close a socket that isn’t open, DDPCloseSocket will return ddpSktErr. Result codes noErr No error ddpSktErr Socket error æKY DDPRead æFc AppleTalk.h æT Function æD pascal OSErr DDPRead(ATDDPRecHandle abRecord,Boolean retCksumErrs,Boolean async); æDT OSErr myVariable = DDPRead((ATDDPRecHandle) abRecord,(Boolean) retCksumErrs,(Boolean) async); æMM æRI II-283 æC ABusRecord <-- abOpcode {always tDDPRead} <-- abResult {result code} --> abUserReference {for your use} <-- ddpType {DDP protocol type} --> ddpSocket {listening socket number} <-- ddpAddress {source socket address} --> ddpReqCount {buffer size in bytes} <-- ddpActCount {number of bytes actually received} --> ddpDataPtr {pointer to buffer} <-- ddpNodeID {original destination node ID} DDPRead receives a datagram from another socket. The size and location of the buffer that will receive the data are specified by ddpReqCount and ddpDataPtr. If the buffer isn’t large enough to hold all of the incoming frame data, the extra bytes will be discarded and buf2SmallErr will be returned. The number of bytes actually received is returned in ddpActCount. DDPSocket specifies the socket to receive the datagram (the “listening” socket). The node to which the packet was sent is returned in ddpNodeID; if the packet was broadcast ddpNodeID will contain 255. The address of the socket that sent the packet is returned in ddpAddress. If retCksumErrs is FALSE, DDPRead will discard any packets received with an invalid checksum and inform the caller of the error. If retCksumErrs is TRUE, DDPRead will deliver all packets, whether or not the checksum is valid; it will also notify the caller when there’s a checksum error. Note: The sender of the datagram must be in a different node from the receiver. You should issue DDPRead calls only for receiving datagrams for sockets opened with the default socket listener; see the description of DDPOpenSocket. Note: If the buffer provided isn’t large enough to hold all of the incoming frame data (buf2SmallErr), the checksum can’t be calculated; in this case, DDPRead will deliver packets even if retCksumErrs is FALSE. Result codes noErr No error buf2SmallErr Datagram too large for buffer cksumErr Checksum error ddpLenErr Datagram length too big ddpSktErr Socket error readQErr Invalid socket or socket not found in table æKY DDPWrite æFc AppleTalk.h æT Function æD pascal OSErr DDPWrite(ATDDPRecHandle abRecord,Boolean doChecksum,Boolean async); æDT OSErr myVariable = DDPWrite((ATDDPRecHandle) abRecord,(Boolean) doChecksum,(Boolean) async); æMM æRI II-283 æC ABusRecord <-- abOpcode {always tDDPWrite} <-- abResult {result code} --> abUserReference {for your use} --> ddpType {DDP protocol type} --> ddpSocket {source socket number} --> ddpAddress {destination socket address} --> ddpReqCount {length of datagram data} --> ddpDataPtr {pointer to buffer} DDPWrite sends a datagram to another socket. DDPReqCount and ddpDataPtr specify the length and location of the data to send. The ddpType field indicates the DDP protocol type of the frame, and ddpAddress is the complete internet address of the socket to which the datagram should be sent. DDPSocket specifies the socket from which the datagram should be sent. Datagrams sent over the internet to a node on an AppleTalk network different from the sending node’s network have an optional software checksum to detect errors that might occur inside the intermediate bridges. If doChecksum is TRUE, DDPWrite will compute this checksum; if it’s FALSE, this software checksum feature is ignored. Note: The destination socket can’t be in the same node as the program making the DDPWrite call. Result codes noErr No error ddpLenErr Datagram length too big ddpSktErr Source socket not open noBridgeErr No bridge found æKY DDPRdCancel æFc AppleTalk.h æT Function æD pascal OSErr DDPRdCancel(ATDDPRecHandle abRecord); æDT OSErr myVariable = DDPRdCancel((ATDDPRecHandle) abRecord); æMM æRI II-284 æC Given the handle to the ABusRecord of a previously made DDPRead call, DDPRdCancel dequeues the DDPRead call, provided that a packet satisfying the DDPRead hasn’t already arrived. DDPRdCancel returns noErr if the DDPRead call is successfully removed from the queue. If DDPRdCancel returns recNotFnd, check the abResult field of abRecord to verify that the DDPRead has been completed and determine its outcome. Result codes noErr No error readQErr Invalid socket or socket not found in table recNotFnd ABRecord not found in queue »Example This example sends a DDP packet synchronously and waits asynchronously for a response. Assume that both nodes are using a known socket number (in this case, 30) to receive packets. Normally, you would want to use NBP to look up your destination’s socket address. VAR myABRecord: ABRecHandle; myBuffer: PACKED ARRAY [0..599] OF CHAR; {buffer for both send and receive} mySocket: Byte; errCode, index, dataLen: INTEGER; someText: Str255; async, retCksumErrs, doChecksum: BOOLEAN; BEGIN errCode := MPPOpen; IF errCode <> noErr THEN WRITELN('Error in opening AppleTalk') {Maybe serial port B isn't available for use by AppleTalk} ELSE BEGIN {Call Memory Manager to allocate ABusRecord} myABRecord := ABRecHandle(NewHandle(ddpSize)); mySocket := 30; {Add mySocket to socket table and install default socket listener to service } { datagrams addressed to that socket. No packets addressed to mySocket will be } { received until we call DDPRead. } errCode := DDPOpenSocket(mySocket, NIL); IF errCode <> noErr THEN WRITELN('Error while opening the socket') {Have we opened too many socket listeners? Remember that DDP uses two of } { them.} ELSE BEGIN {Prepare data to be sent} someText := 'This is a sample datagram'; dataLen := LENGTH(someText); FOR index := 0 TO dataLen - 1 DO {stuff buffer with packet data} myBuffer[index] := someText[index + 1]; async := FALSE; WITH myABRecord^^ DO {fill the parameters in the ABusRecord} BEGIN ddpType := 5; ddpAddress.aNet := 0; {send on “our” network} ddpAddress.aNode := 34; ddpAddress.aSocket := mySocket; ddpReqCount := dataLen; ddpDataPtr := @myBuffer; END; doChecksum := FALSE; {If packet contains a DDP long header, compute checksum and insert it into } { the header.} errCode := DDPWrite(myABRecord, doChecksum, async); {send packet} {In the case of a sync call, errCode and the abResult field of myABRecord } { will contain the same result code. We can also reuse myABRecord, since we } { know whether the call has completed.} IF errCode <> noErr THEN WRITELN('Error while writing out the packet') {Maybe the receiving node wasn't on-line} ELSE BEGIN {We have sent out the packet and are now waiting for a response. We } { issue an async DDPRead call so that we don't “hang” waiting for a } { response that may not come. To cancel the async read call, we must } { close the socket associated with the call or call DDPRdCancel.} async := TRUE; retCksumErrs := TRUE; {return packets even if } { they have a checksum error} WITH myABRecord^^ DO BEGIN ddpSocket := mySocket; ddpReqCount := 600; {our reception buffer is max size} ddpDataPtr := @myBuffer; END; {Wait for a packet asynchronously} errCode := DDPRead(myABRecord, retCksumErrs, async); IF errCode <> noErr THEN WRITELN('Error while trying to queue up a DDPRead') {Was the socket listener installed correctly?} ELSE BEGIN {We can either sit here in a loop and poll the } { abResult field or just exit our code and use the } { event mechanism to flag us when the packet arrives.} CheckForMyEvent; {your procedure for checking for a } { network event} {If there were no errors, a packet is inside the array } { mybuffer, the length is in ddpActCount, and the } { address of the sending socket is in ddpAddress. } { Process the packet received here and report any errors.} errCode := DDPCloseSocket(mySocket); {we're done with it} IF errCode <> noErr THEN WRITELN('Error while closing the socket'); END; END; END; END; END. æKY ATPLoad æFc AppleTalk.h æT Function æD pascal OSErr ATPLoad(void); æDT OSErr myVariable = ATPLoad()(void); æMM æRT 20, 224 æRI II-290, N20-2 æC •••Refer to Technical Note #224:••• ATPLoad first verifies that the .MPP driver is loaded and running. If it isn’t, ATPLoad verifies that port B is configured for AppleTalk and isn’t in use, and then loads MPP into the system heap. ATPLoad then loads the .ATP driver, unless it’s already in memory. On a Macintosh 128K, ATPLoad reads the .ATP driver from the system resource file into the application heap; on a Macintosh 512K or XL, ATP is read into the system heap. Note: On a Macintosh 512K or XL, ATPLoad and MPPOpen perform essentially the same function. Result codes noErr No error portInUse Port B is already in use portNotCf Port B not configured for AppleTalk æKY ATPUnload æFc AppleTalk.h æT Function æD pascal OSErr ATPUnload(void); æDT OSErr myVariable = ATPUnload()(void); æRI II-290 æC ATPUnload makes the .ATP driver purgeable; the space isn’t actually released by the Memory Manager until necessary. Note: This call applies only to a Macintosh 128K; on a Macintosh 512K or Macintosh XL, ATPUnload has no effect. Result codes noErr No error æKY ATPOpenSocket æFc AppleTalk.h æT Function æD pascal OSErr ATPOpenSocket(const AddrBlock *addrRcvd,short *atpSocket); æDT OSErr myVariable = ATPOpenSocket((const AddrBlock *) addrRcvd,(short *) atpSocket); æMM æRI II-290 æC ATPOpenSocket opens a socket for the purpose of receiving requests. ATPSocket contains the socket number of the socket to open; if it’s 0, a number is dynamically assigned and returned in atpSocket. AddrRcvd contains a filter of the sockets from which requests will be accepted. A 0 in the network number, node ID, or socket number field of the addrRcvd record acts as a “wild card”; for instance, a 0 in the socket number field means that requests will be accepted from all sockets in the node(s) specified by the network and node fields. Result codes noErr No error tooManySkts Socket table full noDataArea Too many outstanding ATP calls Note: If you’re only going to send requests and receive responses to these requests, you don’t need to open an ATP socket. When you make the ATPSndRequest or ATPRequest call, ATP automatically opens a dynamically assigned socket for that purpose. æKY ATPCloseSocket æFc AppleTalk.h æT Function æD pascal OSErr ATPCloseSocket(short atpSocket); æDT OSErr myVariable = ATPCloseSocket((short) atpSocket); æMM æRI II-291 æC ATPCloseSocket closes the responding socket whose number is specified by atpSocket. It releases the data structures associated with all pending, asynchronous calls involving that socket; these pending calls are completed immediately and return the result code sktClosed. Result codes noErr No error noDataArea Too many outstanding ATP calls æKY ATPSndRequest æFc AppleTalk.h æT Function æD pascal OSErr ATPSndRequest(ATATPRecHandle abRecord,Boolean async); æDT OSErr myVariable = ATPSndRequest((ATATPRecHandle) abRecord,(Boolean) async); æMM æRI II-291 æC ABusRecord <-- abOpcode {always tATPSndRequest} <-- abResult {result code} --> abUserReference {for your use} --> atpAddress {destination socket address} --> atpReqCount {request size in bytes} --> atpDataPtr {pointer to buffer} --> atpRspBDSPtr {pointer to response BDS} --> atpUserData {user bytes} --> atpXO {exactly-once flag} <-- atpEOM {end-of-message flag} --> atpTimeOut {retry timeout interval in seconds} --> atpRetries {maximum number of retries} --> atpNumBufs {number of elements in response BDS} <-- atpNumRsp {number of response packets actually received} ATPSndRequest sends a request to another socket. ATPAddress is the internet address of the socket to which the request should be sent. ATPDataPtr and atpReqCount specify the location and size of a buffer that contains the request information to be sent. ATPUserData contains the user bytes for the ATP header. ATPSndRequest requires you to allocate a response BDS. ATPRspBDSPtr is a pointer to the response BDS; atpNumBufs indicates the number of elements in the BDS (this is also the maximum number of response datagrams that will be accepted). The number of response datagrams actually received is returned in atpNumRsp; if a nonzero value is returned, you can examine the response BDS to determine which packets of the transaction were actually received. If the number returned is less than requested, one of the following is true: • Some of the packets have been lost and the retry count has been exceeded. • ATPEOM is TRUE; this means that the response consisted of fewer packets than were expected, but that all packets sent were received (the last packet came with the atpEOM flag set). ATPTimeOut indicates the length of time that ATPSndRequest should wait for a response before retransmitting the request. ATPRetries indicates the maximum number of retries ATPSndRequest should attempt. ATPXO should be TRUE if you want the request to be part of an exactly-once transaction. ATPSndRequest completes when either the transaction is completed or the retry count is exceeded. Result codes noErr No error reqFailed Retry count exceeded tooManyReqs Too many concurrent requests noDataArea Too many outstanding ATP calls æKY ATPRequest æFc AppleTalk.h æT Function æD pascal OSErr ATPRequest(ATATPRecHandle abRecord,Boolean async); æDT OSErr myVariable = ATPRequest((ATATPRecHandle) abRecord,(Boolean) async); æMM æRI II-292 æC ABusRecord <-- abOpcode {always tATPRequest} <-- abResult {result code} --> abUserReference {for your use} --> atpAddress {destination socket address} --> atpReqCount {request size in bytes} --> atpDataPtr {pointer to buffer} <-- atpActCount {number of bytes actually received} --> atpUserData {user bytes} --> atpXO {exactly-once flag} <-- atpEOM {end-of-message flag} --> atpTimeOut {retry timeout interval in seconds} --> atpRetries {maximum number of retries} <-- atpRspUData {user bytes received in transaction response} --> atpRspBuf {pointer to response message buffer} --> atpRspSize {size of response message buffer} ATPRequest is functionally analogous to ATPSndRequest. It sends a request to another socket, but doesn’t require the caller to set up and use the BDS data structure to describe the response buffers. ATPAddress indicates the socket to which the request should be sent. ATPDataPtr and atpReqCount specify the location and size of a buffer that contains the request information to be sent. ATPUserData contains the user bytes to be sent in the request’s ATP header. ATPTimeOut indicates the length of time that ATPRequest should wait for a response before retransmitting the request. ATPRetries indicates the maximum number of retries ATPRequest should attempt. To use this call, you must have an area of contiguous buffer space that’s large enough to receive all expected datagrams. The various datagrams will be assembled in this buffer and returned to you as a complete message upon completion of the transaction. The location and size of this buffer are passed in atpRspBuf and atpRspSize. Upon completion of the call, the size of the received response message is returned in atpActCount. The user bytes received in the ATP header of the first response packet are returned in atpRspUData. ATPXO should be TRUE if you want the request to be part of an exactly-once transaction. Although you don’t provide a BDS, ATPRequest in fact creates one and calls the .ATP driver (as in an ATPSndRequest call). For this reason, the abRecord fields atpRspBDSPtr and atpNumBufs are used by ATPRequest; you should not expect these fields to remain unaltered during or after the function’s execution. For ATPRequest to receive and correctly deliver the response as a single message, the responding end must, upon receiving the request (with an ATPGetRequest call), generate the complete response as a message in a single buffer and then call ATPResponse. Note: The responding end could also use ATPSndRsp and ATPAddRsp provided that each response packet (except the last one) contains exactly 578 ATP data bytes; the last packet in the response can contain less than 578 ATP data bytes. Also, if this method is used, only the ATP user bytes of the first response packet will be delivered to the requester; any information in the user bytes of the remaining response packets will not be delivered. ATPRequest completes when either the transaction is completed or the retry count is exceeded. Result codes noErr No error reqFailed Retry count exceeded tooManyReqs Too many concurrent requests sktClosed Socket closed by a cancel call noDataArea Too many outstanding ATP calls æKY ATPReqCancel æFc AppleTalk.h æT Function æD pascal OSErr ATPReqCancel(ATATPRecHandle abRecord,Boolean async); æDT OSErr myVariable = ATPReqCancel((ATATPRecHandle) abRecord,(Boolean) async); æMM æRI II-293 æC Given the handle to the ABusRecord of a previously made ATPSndRequest or ATPRequest call, ATPReqCancel dequeues the ATPSndRequest or ATPRequest call, provided that the call hasn’t already completed. ATPReqCancel returns noErr if the ATPSndRequest or ATPRequest call is successfully removed from the queue. If it returns cbNotFound, check the abResult field of abRecord to verify that the ATPSndRequest or ATPRequest call has completed and determine its outcome. Result codes noErr No error cbNotFound ATP control block not found æKY ATPGetRequest æFc AppleTalk.h æT Function æD pascal OSErr ATPGetRequest(ATATPRecHandle abRecord,Boolean async); æDT OSErr myVariable = ATPGetRequest((ATATPRecHandle) abRecord,(Boolean) async); æMM æRT 20 æRI II-293, N20-2 æC ABusRecord <-- abOpcode {always tATPGetRequest} <-- abResult {result code} --> abUserReference {for your use} --> atpSocket {listening socket number} <-- atpAddress {source socket address} --> atpReqCount {buffer size in bytes} --> atpDataPtr {pointer to buffer} <-- atpBitMap {transaction bit map} <-- atpTransID {transaction ID} <-- atpActCount {number of bytes actually received} <-- atpUserData {user bytes} <-- atpXO {exactly-once flag} ATPGetRequest sets up the mechanism to receive a request sent by either an ATPSndRequest or an ATPRequest call. ATPSocket contains the socket number of the socket that should listen for a request; this socket must already have been opened by calling ATPOpenSocket. The address of the socket from which the request was sent is returned in atpAddress. ATPDataPtr specifies a buffer to store the incoming request; atpReqCount indicates the size of the buffer in bytes. The number of bytes actually received in the request is returned in atpActCount. ATPUserData contains the user bytes from the ATP header. The transaction bit map is returned in atpBitMap. The transaction ID is returned in atpTransID. ATPXO will be TRUE if the request is part of an exactly-once transaction. ATPGetRequest completes when a request is received. To cancel an asynchronous ATPGetRequest call, you must call ATPCloseSocket, but this cancels all pending calls involving that socket. Result codes noErr No error badATPSkt Bad responding socket sktClosed Socket closed by a cancel call æKY ATPSndRsp æFc AppleTalk.h æT Function æD pascal OSErr ATPSndRsp(ATATPRecHandle abRecord,Boolean async); æDT OSErr myVariable = ATPSndRsp((ATATPRecHandle) abRecord,(Boolean) async); æMM æRI II-294 æC ABusRecord <-- abOpcode {always tATPSdRsp} <-- abResult {result code} --> abUserReference {for your use} --> atpSocket {responding socket number} --> atpAddress {destination socket address} --> atpRspBDSPtr {pointer to response BDS} --> atpTransID {transaction ID} --> atpEOM {end-of-message flag} --> atpNumBufs {number of response packets being sent} --> atpBDSSize {number of elements in response BDS} ATPSndRsp sends a response to another socket. ATPSocket contains the socket number from which the response should be sent and atpAddress contains the internet address of the socket to which the response should be sent. ATPTransID must contain the transaction ID. ATPEOM is TRUE if the response BDS contains the final packet in a transaction composed of a group of packets and the number of packets in the response is less than expected. ATPRspBDSPtr points to the buffer data structure containing the responses to be sent. ATPBDSSize indicates the number of elements in the response BDS, and must be in the range 1 to 8. ATPNumBufs indicates the number of response packets being sent with this call, and must be in the range 0 to 8. Note: In some situations, you may want to send only part (or possibly none) of your response message back immediately. For instance, you might be requested to send back seven disk blocks, but have only enough internal memory to store one block. In this case, set atpBDSSize to 7 (total number of response packets), atpNumBufs to 0 (number of response packets currently being sent), and call ATPSndRsp. Then as you read in one block at a time, call ATPAddRsp until all seven response datagrams have been sent. During exactly-once transactions, ATPSndRsp won’t complete until the release packet is received or the release timer expires. Result codes noErr No error badATPSkt Bad responding socket noRelErr No release received sktClosed Socket closed by a cancel call noDataArea Too many outstanding ATP calls badBuffNum Bad sequence number æKY ATPAddRsp æFc AppleTalk.h æT Function æD pascal OSErr ATPAddRsp(ATATPRecHandle abRecord); æDT OSErr myVariable = ATPAddRsp((ATATPRecHandle) abRecord); æMM æRI II-295 æC ABusRecord <-- abOpcode {always tATPAddRsp} <-- abResult {result code} --> abUserReference {for your use} --> atpSocket {responding socket number} --> atpAddress {destination socket address} --> atpReqCount {buffer size in bytes} --> atpDataPtr {pointer to buffer} --> atpTransID {transaction ID} --> atpUserData {user bytes} --> atpEOM {end-of-message flag} --> atpNumRsp {sequence number} ATPAddRsp sends one additional response packet to a socket that has already been sent the initial part of a response via ATPSndRsp. ATPSocket contains the socket number from which the response should be sent and atpAddress contains the internet address of the socket to which the response should be sent. ATPTransID must contain the transaction ID. ATPDataPtr and atpReqCount specify the location and size of a buffer that contains the information to send; atpNumRsp is the sequence number of the response. ATPEOM is TRUE if this response datagram is the final packet in a transaction composed of a group of packets. ATPUserData contains the user bytes to be sent in this response datagram’s ATP header. Note: No BDS is needed with ATPAddRsp because all pertinent information is passed within the record. Result codes noErr No error badATPSkt Bad responding socket badBuffNum Bad sequence number noSendResp ATPAddRsp issued before ATPSndRsp noDataArea Too many outstanding ATP calls æKY ATPResponse æFc AppleTalk.h æT Function æD pascal OSErr ATPResponse(ATATPRecHandle abRecord,Boolean async); æDT OSErr myVariable = ATPResponse((ATATPRecHandle) abRecord,(Boolean) async); æMM æRT 20 æRI II-296, N20-2 æC ABusRecord <-- abOpcode {always tATPResponse} <-- abResult {result code} --> abUserReference {for your use} --> atpSocket {responding socket number} --> atpAddress {destination socket address} --> atpTransID {transaction ID) --> atpRspUData {user bytes sent in transaction response} --> atpRspBuf {pointer to response message buffer} --> atpRspSize {size of response message buffer} ATPResponse is functionally analogous to ATPSndRsp. It sends a response to another socket, but doesn’t require the caller to provide a BDS. ATPAddress must contain the complete network address of the socket to which the response should be sent (taken from the data provided by an ATPGetRequest call). ATPTransID must contain the transaction ID. ATPSocket indicates the socket from which the response should be sent (the socket on which the corresponding ATPGetRequest was issued). ATPRspBuf points to the buffer containing the response message; the size of this buffer must be passed in atpRspSize. The four user bytes to be sent in the ATP header of the first response packet are passed in atpRspUData. The last packet of the transaction response is sent with the EOM flag set. Although you don’t provide a BDS, ATPResponse in fact creates one and calls the .ATP driver (as in an ATPSndRsp call). For this reason, the abRecord fields atpRspBDSPtr and atpNumBufs are used by ATPResponse; you should not expect these fields to remain unaltered during or after the function’s execution. During exactly-once transactions ATPResponse won’t complete until the release packet is received or the release timer expires. Warning: The maximum permissible size of the response message is 4624 bytes. Result codes noErr No error badATPSkt Bad responding socket noRelErr No release received atpLenErr Response too big sktClosed Socket closed by a cancel call noDataArea Too many outstanding ATP calls æKY ATPRspCancel æFc AppleTalk.h æT Function æD pascal OSErr ATPRspCancel(ATATPRecHandle abRecord,Boolean async); æDT OSErr myVariable = ATPRspCancel((ATATPRecHandle) abRecord,(Boolean) async); æMM æRI II-296 æC Given the handle to the ABusRecord of a previously made ATPSndRsp or ATPResponse call, ATPRspCancel dequeues the ATPSndRsp or ATPResponse call, provided that the call hasn’t already completed. ATPRspCancel returns noErr if the ATPSndRsp or ATPResponse call is successfully removed from the queue. If it returns cbNotFound, check the abResult field of abRecord to verify that the ATPSndRsp or ATPResponse call has completed and determine its outcome. Result codes noErr No error cbNotFound ATP control block not found »Example This example shows the requesting side of an ATP transaction that asks for a 512-byte disk block from the responding end. The block number of the file is a byte and is contained in myBuffer[0]. VAR myABRecord: ABRecHandle; myBDSPtr: BDSPtr; myBuffer: PACKED ARRAY [0..511] OF CHAR; errCode: INTEGER; async: BOOLEAN; BEGIN errCode := ATPLoad; IF errCode <> noErr THEN WRITELN('Error in opening AppleTalk') {Maybe serial port B isn't available for use by AppleTalk} ELSE BEGIN {Prepare the BDS; allocate space for a one-element BDS} myBDSPtr := BDSPtr(NewPtr(SIZEOF(BDSElement))); WITH myBDSPtr^[0] DO BEGIN buffSize := 512; {size of our buffer used in reception} buffPtr := @myBuffer; {pointer to the buffer} END; {Prepare the ABusRecord} myBuffer[0] := CHR(1); {requesting disk block number 1} myABRecord := ABRecHandle(NewHandle(atpSize)); WITH myABRecord^^ DO BEGIN atpAddress.aNet := 0; atpAddress.aNode := 30; {we probably got this from an NBP call} atpAddress.aSocket := 15; {socket to send request to} atpReqCount := 1; {size of request data field (disk block #)} atpDataPtr := @myBuffer; {ptr to request to be sent} atpRspBDSPtr := @myBDSPtr; atpUserData := 0; {for your use} atpXO := FALSE; {at-least-once service} atpTimeOut := 5; {5-second timeout} atpRetries := 3; {3 retries; request will be sent 4 times max} atpNumBufs := 1; {we're only expecting 1 block to be returned} END; async := FALSE; {Send the request and wait for the response} errCode := ATPSndRequest(myABRecord, async); IF errCode <> noErr THEN WRITELN('An error occurred in the ATPSndRequest call') ELSE BEGIN {The disk block requested is now in myBuffer. We can verify } { that atpNumRsp contains 1, meaning one response received.} . . . END; END; END. æKY NBPRegister æFc AppleTalk.h æT Function æD pascal OSErr NBPRegister(ATNBPRecHandle abRecord,Boolean async); æDT OSErr myVariable = NBPRegister((ATNBPRecHandle) abRecord,(Boolean) async); æMM æRT 20 æRI II-299, N20-2 æC ABusRecord <-- abOpcode {always tNBPRegister} <-- abResult {result code} --> abUserReference {for your use} --> nbpEntityPtr {pointer to entity name} --> nbpBufPtr {pointer to buffer} --> nbpBufSize {buffer size in bytes} --> nbpAddress.aSocket {socket address} --> nbpRetransmitInfo {retransmission information} NBPRegister adds the name and address of an entity to the node’s names table. NBPEntityPtr points to a variable of type EntityName containing the entity’s name. If the name is already registered, NBPRegister returns the result code nbpDuplicate. NBPAddress indicates the socket for which the name should be registered. NBPBufPtr and nbpBufSize specify the location and size of a buffer for NBP to use internally. While the variable of type EntityName is declared as three 32-byte strings, only the actual characters of the name are placed in the buffer pointed to by nbpBufPtr. For this reason, nbpBufSize needs only to be equal to the actual length of the name, plus an additional 12 bytes for use by NBP. Warning: This buffer must not be altered or released until the name is removed from the names table via an NBPRemove call. If you allocate the buffer through a NewHandle call, you must lock it as long as the name is registered. Warning: The zone field of the entity name must be set to the meta-character “*”. Result codes noErr No error nbpDuplicate Duplicate name already exists æKY NBPLookup æFc AppleTalk.h æT Function æD pascal OSErr NBPLookup(ATNBPRecHandle abRecord,Boolean async); æDT OSErr myVariable = NBPLookup((ATNBPRecHandle) abRecord,(Boolean) async); æMM æRT 9, 20 æRI II-300, N9-1, 2, N20-2 æC ABusRecord <-- abOpcode {always tNBPLookup} <-- abResult {result code} --> abUserReference {for your use} --> nbpEntityPtr {pointer to entity name} --> nbpBufPtr {pointer to buffer} --> nbpBufSize {buffer size in bytes} <-> nbpDataField {number of addresses received} --> nbpRetransmitInfo {retransmission information} NBPLookup returns the addresses of all entities with a specified name. NBPEntityPtr points to a variable of type EntityName containing the name of the entity whose address should be returned. (Meta-characters are allowed in the entity name.) NBPBufPtr and nbpBufSize contain the location and size of an area of memory in which the entity names and their corresponding addresses should be returned. NBPDataField indicates the maximum number of matching names to find addresses for; the actual number of addresses found is returned in nbpDataField. NBPRetransmitInfo contains the retry interval and the retry count. When specifying nbpBufSize, for each NBP tuple expected, allow space for the actual characters of the name, the address, and four bytes for use by NBP. Result codes noErr No error nbpBuffOvr Buffer overflow æKY NBPExtract æFc AppleTalk.h æT Function æD pascal OSErr NBPExtract(Ptr theBuffer,short numInBuf,short whichOne,EntityName *abEntity, AddrBlock *address); æDT OSErr myVariable = NBPExtract((Ptr) theBuffer,(short) numInBuf,(short) whichOne,(EntityName *) abEntity,( AddrBlock) * address); æMM æRI II-300,V-515 æC This routine is provided in the alternate interface, but can be used as provided for extracting NBP entity names from a look-up response buffer. NBPExtract returns one address from the list of addresses returned by NBPLookup. TheBuffer and numInBuf indicate the location and number of tuples in the buffer. WhichOne specifies which one of the tuples in the buffer should be returned in the abEntity and address parameters. Result codes noErr No error extractErr Can’t find tuple in buffer æKY NBPConfirm æFc AppleTalk.h æT Function æD pascal OSErr NBPConfirm(ATNBPRecHandle abRecord,Boolean async); æDT OSErr myVariable = NBPConfirm((ATNBPRecHandle) abRecord,(Boolean) async); æMM æRT 9 æRI II-301, N9-2 æC ABusRecord <-- abOpcode {always tNBPConfirm} <-- abResult {result code} --> abUserReference {for your use} --> nbpEntityPtr {pointer to entity name} <-- nbpDataField {socket number} --> nbpAddress {socket address} --> nbpRetransmitInfo {retransmission information} NBPConfirm confirms that an entity known by name and address still exists (is still entered in the names directory). NBPEntityPtr points to a variable of type EntityName that contains the name to confirm, and nbpAddress specifies the address to be confirmed. (No meta-characters are allowed in the entity name.) NBPRetransmitInfo contains the retry interval and the retry count. The socket number of the entity is returned in nbpDataField. NBPConfirm is more efficient than NBPLookup in terms of network traffic. Result codes noErr No error nbpConfDiff Name confirmed for different socket nbpNoConfirm Name not confirmed æKY NBPRemove æFc AppleTalk.h æT Function æD pascal OSErr NBPRemove(EntityPtr abEntity); æDT OSErr myVariable = NBPRemove((EntityPtr) abEntity); æMM æRI II-301 æC NBPRemove removes an entity name from the names table of the given entity’s node. Result codes noErr No error nbpNotFound Name not found æKY NBPLoad æFc AppleTalk.h æT Function æD pascal OSErr NBPLoad(void); æDT OSErr myVariable = NBPLoad()(void); æMM æRI II-301 æC On a Macintosh 128K, NBPLoad reads the NBP code from the system resource file into the application heap. On a Macintosh 512K or XL, NBPLoad has no effect since the NBP code should have already been loaded when the .MPP driver was opened. Normally you’ll never need to call NBPLoad, because the AppleTalk Manager calls it when necessary. Result codes noErr No error æKY NBPUnload æFc AppleTalk.h æT Function æD pascal OSErr NBPUnload(void); æDT OSErr myVariable = NBPUnload()(void); æMM æRI II-301 æC On a Macintosh 128K, NBPUnload makes the NBP code purgeable; the space isn’t actually released by the Memory Manager until necessary. On a Macintosh 512K or Macintosh XL, NBPUnload has no effect. Result codes noErr No error »Example This example of NBP registers our node as a print spooler, searches for any print spoolers registered on the network, and then extracts the information for the first one found. CONST mySocket = 20; VAR myABRecord: ABRecHandle; myEntity: EntityName; entityAddr: AddrBlock; nbpNamePtr: Ptr; myBuffer: PACKED ARRAY [0..999] OF CHAR; errCode: INTEGER; async: BOOLEAN; BEGIN errCode := MPPOpen; IF errCode <> noErr THEN WRITELN('Error in opening AppleTalk') {Maybe serial port B isn't available for use by AppleTalk} ELSE BEGIN {Call Memory Manager to allocate ABusRecord} myABRecord := ABRecHandle(NewHandle(nbpSize)); {Set up our entity name to register} WITH myEntity DO BEGIN objStr := 'Gene Station'; {we are called 'Gene Station' } typeStr := 'PrintSpooler'; { and are of type 'PrintSpooler'} zoneStr := '*'; {Allocate data space for the entity name (used by NBP)} nbpNamePtr := NewPtr(LENGTH(objStr) + LENGTH(typeStr) + LENGTH(zoneStr) + 12); END; {Set up the ABusRecord for the NBPRegister call} WITH myABRecord^^ DO BEGIN nbpEntityPtr := @myEntity; nbpBufPtr := nbpNamePtr; {buffer used by NBP internally} nbpBufSize := nbpNameBufSize; nbpAddress.aSocket := mySocket; {socket to register us on} nbpRetransmitInfo.retransInterval := 8; {retransmit every 64 } nbpRetransmitInfo.retransCount := 3; { ticks and try 3 times} END; async := FALSE; errCode := NBPRegister(myABRecord, async); IF errCode <> noErr THEN WRITELN('Error occurred in the NBPRegister call') {Maybe the name is already registered somewhere else on the } { network.} ELSE BEGIN {Now that we've registered our name, find others of type } { 'PrintSpooler'.} WITH myEntity DO BEGIN objStr := '='; {any one of type } typeStr := 'PrintSpooler'; { “PrintSpooler” } zoneStr := '*'; { in our zone} END; WITH myABRecord^^ DO BEGIN nbpEntityPtr := @myEntity; nbpBufPtr := @myBuffer; {buffer to place responses in} nbpBufSize := SIZEOF(myBuffer); {The field nbpDataField, before the NBPLookup call, represents an } { approximate number of responses. After the call, nbpDataField } { contains the actual number of responses received.} nbpDataField := 100; {we want about 100 responses back} END; errCode := NBPLookup(myABRecord, async); {make sync call} IF errCode <> noErr THEN WRITELN('An error occurred in the NBPLookup') {Did the buffer overflow?} ELSE BEGIN {Get the first reply} errCode := NBPExtract(@mybuffer, myABRecord^^.nbpDataField, 1, myEntity, entityAddr); {The socket address and name of the entity are returned here. If we } { want all of them, we'll have to loop for each one in the buffer.} IF errCode <> noErr THEN WRITELN('Error in NBPExtract'); {Maybe the one we wanted wasn't in the buffer} END; END; END; END. æKY RemoveHdlBlocks æFc AppleTalk.h æT Function æD pascal void RemoveHdlBlocks(void); æDT RemoveHdlBlocks()(void); æC æKY GetNodeAddress æFc AppleTalk.h æT Function æD pascal OSErr GetNodeAddress(short *myNode,short *myNet); æDT OSErr myVariable = GetNodeAddress((short *) myNode,(short *) myNet); æRI II-303 æC GetNodeAddress returns the current node ID and network number of the caller. If the .MPP driver isn’t installed, it returns noMPPErr. If myNet contains 0, this means that a bridge hasn’t yet been found. Result codes noErr No error noMPPErr MPP driver not installed æKY IsMPPOpen æFc AppleTalk.h æT Function æD pascal Boolean IsMPPOpen(void); æDT Boolean myVariable = IsMPPOpen()(void); æRI II-304 æC [Not in ROM] IsMPPOpen returns TRUE if the .MPP driver is loaded and running. æKY IsATPOpen æFc AppleTalk.h æT Function æD pascal Boolean IsATPOpen(void); æDT Boolean myVariable = IsATPOpen()(void); æRI II-304 æC [Not in ROM] IsATPOpen returns TRUE if the .ATP driver is loaded and running. æKY Assert.h æC assert #include <Assert.h> void assert (int expression); Description The assert; macro allows your program to send diagnostic messages to the user, depending on the evaluation of expression. If expression is false, assert provides an error message, and then calls the abort function. The format for this message is FILE myfile.c; Line 108 ##assertion failed: i<j The assert macro can be activated using the NDEBUG macro. If NDEBUG is turned off, assert will evaluate expression. Note The message pointed to by assert is an executable MPW command. When the command is executed, it will open the source file containing the assert and highlight the assert statement. Example #include <assert.h> main() { int i,j; i = foo(); j = 3; assert (i<100); /* This depends on the compile-time */ /* setting of NDEBUG. If */ /* NDEBUG is defined, the assert */ /* statement is not passed from the */ /* preprocessor to the compiler */ #undef NDEBUG /* Turn off NDEBUG */ #include <assert.h> assert (i<j); /* This assert is turned on */ #define NDEBUG /* Turn on NDEBUG */ #include <assert.h> j = foo(); assert (j <100); /* This assert is turned off */ } See also abort æKY assert æFc Assert.h æC #include <Assert.h> void assert (int expression); Description The assert; macro allows your program to send diagnostic messages to the user, depending on the evaluation of expression. If expression is false, assert provides an error message, and then calls the abort function. The format for this message is FILE myfile.c; Line 108 ##assertion failed: i<j The assert macro can be activated using the NDEBUG macro. If NDEBUG is turned off, assert will evaluate expression. Note The message pointed to by assert is an executable MPW command. When the command is executed, it will open the source file containing the assert and highlight the assert statement. Example #include <assert.h> main() { int i,j; i = foo(); j = 3; assert (i<100); /* This depends on the compile-time */ /* setting of NDEBUG. If */ /* NDEBUG is defined, the assert */ /* statement is not passed from the */ /* preprocessor to the compiler */ #undef NDEBUG /* Turn off NDEBUG */ #include <assert.h> assert (i<j); /* This assert is turned on */ #define NDEBUG /* Turn on NDEBUG */ #include <assert.h> j = foo(); assert (j <100); /* This assert is turned off */ } See also abort æKY assertæ æDT void myVariable = assert ((int) expression); æKY Balloons.h æKL HMBalloonRect HMBaloonPict HMExtractHelpMsg HMFillCitationString HMGetBalloons HMGetDialogResID HMGetFont HMGetFontSize HMGetMenuResID HMIsBalloon HMMouseInApplRgn HMRemoveBalloon HMScanTemplateItems HMSetBalloons HMSetDialogResID HMSetFont HMSetFontSize HMSetMenuResID HMShowBalloon HMShowMenuBalloon hdlgLocalCoords hdlgSaveBits hdlgUseSubID helpItem hmBadSelector hmBalloonAborted HMCompareItem hmCouldNotLoadPackage HMDefaultRecord HMDefaultRecPtr hmGestaltBalloonsOff hmGestaltBalloonsOn hmGestaltHelpType hmHelpDisabled HMLHHandleType hmMemFullErr HMMessageRecord HMMessageRecordPtr HMNamedResourceItem HMPicHDefaultRecord HMPicHDefaultRecPtr HMPicHMsgRecord HMPicHMsgRecPtr HMPictDefaultRecord HMPictDefaultRecPtr HMPictItem HMPictMsgRecord HMPictMsgRecPtr hmResNotFound hmSameAsLastBalloon HMSkipItem hmSkippedBalloon HMSTHandleType HMStringDefaultRecord HMStringDefaultRecPtr HMStringItem HMStringMsgRecord HMStringMsgRecPtr HMStringRecord HMStringResItem HMStringResType HMStrResDefaultRecord HMStrResDefaultRecPtr HMSTRResItem HMStrResMsgRecord HMStrResMsgRecPtr HMTEHDefaultRecord HMTEHDefaultRecPtr HMTEHMsgRecord HMTEHMsgRecPtr HMTEResItem HMTEResType HMTEStyleType HMTrackCntlItem hmUnknownHelpType HMVersionWord hmWrongVersion hwinUseResID hwinUseSubID kBalloonWDEFID kHMAboutHelpID kHMChecked kHMCheckedItem kHMDisabled kHMDisabledItem kHMEasy1Access kHMEasy2Access kHMEasy3Access kHMEnabled kHMEnabledItem kHMHelpIconOff kHMHelpIconOn kHMHelpID kHMHelpMenuID kHMhrctAbsolute kHMInDisabledScrollBar kHMInDragIndex kHMInGoAwayIndex kHMInGrowIndex kHMInScrollBar kHMInZoomIndex kHMMenuTitleIndex khmmPict khmmPictHandle khmmString khmmStringRes khmmSTRRes khmmTEHandle khmmTERes kHMMultiFinderIndex kHMOther kHMOtherItem kHMUsingHelpIndex kHMUsingHelpItem kHMWhatIsIndex kHMWhatIsItem æKY HMVersionWord æFc Balloons.h æT #define æD #define HMVersionWord 0x0002 æC æKY hmHelpDisabled æFc Balloons.h æT #define æD /* Help Mgr error range: -850 to -874 */ #define hmHelpDisabled -850 æC æKY hmResNotFound æFc Balloons.h æT #define æD #define hmResNotFound -851 æC æKY hmMemFullErr æFc Balloons.h æT #define æD #define hmMemFullErr -852 æC æKY hmBalloonAborted æFc Balloons.h æT #define æD #define hmBalloonAborted -853 æC æKY hmSameAsLastBalloon æFc Balloons.h æT #define æD #define hmSameAsLastBalloon -854 æC æKY hmBadSelector æFc Balloons.h æT #define æD #define hmBadSelector -856 æC æKY hmSkippedBalloon æFc Balloons.h æT #define æD #define hmSkippedBalloon -857 æC æKY hmWrongVersion æFc Balloons.h æT #define æD #define hmWrongVersion -858 æC æKY hmUnknownHelpType æFc Balloons.h æT #define æD #define hmUnknownHelpType -859 æC æKY hmCouldNotLoadPackage æFc Balloons.h æT #define æD #define hmCouldNotLoadPackage -860 æC æKY hmGestaltHelpType æFc Balloons.h æT #define æD /* Gestalt */ #define hmGestaltHelpType 'help' æC æKY hmGestaltBalloonsOn æFc Balloons.h æT #define æD #define hmGestaltBalloonsOn 0 æC æKY hmGestaltBalloonsOff æFc Balloons.h æT #define æD #define hmGestaltBalloonsOff 1 æC æKY kHMUsingHelpItem æFc Balloons.h æT #define æD #define kHMUsingHelpItem 1 æC æKY kHMWhatIsItem æFc Balloons.h æT #define æD #define kHMWhatIsItem 3 æC æKY kHMHelpID æFc Balloons.h æT #define æD #define kHMHelpID -5696 æC æKY kHMMultiFinderIndex æFc Balloons.h æT #define æD /* System STR# resource indexes */ #define kHMMultiFinderIndex 1 æC æKY kHMMenuTitleIndex æFc Balloons.h æT #define æD #define kHMMenuTitleIndex 2 æC æKY kHMUsingHelpIndex æFc Balloons.h æT #define æD #define kHMUsingHelpIndex 3 æC æKY kHMWhatIsIndex æFc Balloons.h æT #define æD #define kHMWhatIsIndex 4 æC æKY kHMInDragIndex æFc Balloons.h æT #define æD #define kHMInDragIndex 5 æC æKY kHMInGrowIndex æFc Balloons.h æT #define æD #define kHMInGrowIndex 6 æC æKY kHMInGoAwayIndex æFc Balloons.h æT #define æD #define kHMInGoAwayIndex 7 æC æKY kHMInZoomIndex æFc Balloons.h æT #define æD #define kHMInZoomIndex 8 æC æKY kHMInScrollBar æFc Balloons.h æT #define æD #define kHMInScrollBar 9 æC æKY kHMInDisabledScrollBar æFc Balloons.h æT #define æD #define kHMInDisabledScrollBar 10 æC æKY kHMEasy1Access æFc Balloons.h æT #define æD #define kHMEasy1Access 11 æC æKY kHMEasy2Access æFc Balloons.h æT #define æD #define kHMEasy2Access 12 æC æKY kHMEasy3Access æFc Balloons.h æT #define æD #define kHMEasy3Access 13 æC æKY kHMAboutHelpID æFc Balloons.h æT #define æD /* misc Constants */ #define kHMAboutHelpID -5696 æC æKY kHMHelpMenuID æFc Balloons.h æT #define æD #define kHMHelpMenuID -5696 æC æKY kHMHelpIconOn æFc Balloons.h æT #define æD #define kHMHelpIconOn -5696 æC æKY kHMHelpIconOff æFc Balloons.h æT #define æD #define kHMHelpIconOff -5695 æC æKY kBalloonWDEFID æFc Balloons.h æT #define æD /* WhatIs default WDEF res ID */ #define kBalloonWDEFID 126 æC æKY helpItem æFc Balloons.h æT #define æD /* Dialog item template type */ #define helpItem 1 æC æKY kHMhrctAbsolute æFc Balloons.h æT #define æD /* hrct Options */ #define kHMhrctAbsolute 0 æC æKY kHMEnabledItem æFc Balloons.h æT #define æD /* Generic defines for the switch items used in 'hmnu' & 'hdlg' */ #define kHMEnabledItem 0 æC æKY kHMDisabledItem æFc Balloons.h æT #define æD #define kHMDisabledItem 1 æC æKY kHMCheckedItem æFc Balloons.h æT #define æD #define kHMCheckedItem 2 æC æKY kHMOtherItem æFc Balloons.h æT #define æD #define kHMOtherItem 3 æC æKY hdlgUseSubID æFc Balloons.h æT #define æD #define hdlgUseSubID 0 /* if set then use sub ID's to fine res ID*/ æC æKY hdlgLocalCoords æFc Balloons.h æT #define æD #define hdlgLocalCoords 1 /* if set then use hdlg rects as local coords, ignoring item rects*/ æC æKY hdlgSaveBits æFc Balloons.h æT #define æD #define hdlgSaveBits 2 /* if set then use save bits behind balloon*/ æC æKY hwinUseResID æFc Balloons.h æT #define æD /* Option bits for hwin resources */ #define hwinUseResID 0 æC æKY hwinUseSubID æFc Balloons.h æT #define æD #define hwinUseSubID 1 æC æKY HMStringItem æFc Balloons.h æT #define æD /* Constants for Help Types in 'hmnu', 'hdlg', 'hrct' resources */ #define HMStringItem 1 æC æKY HMPictItem æFc Balloons.h æT #define æD #define HMPictItem 2 æC æKY HMStringResItem æFc Balloons.h æT #define æD #define HMStringResItem 3 æC æKY HMTEResItem æFc Balloons.h æT #define æD #define HMTEResItem 6 æC æKY HMSTRResItem æFc Balloons.h æT #define æD #define HMSTRResItem 7 æC æKY HMSkipItem æFc Balloons.h æT #define æD #define HMSkipItem 256 æC æKY HMCompareItem æFc Balloons.h æT #define æD #define HMCompareItem 512 æC æKY HMNamedResourceItem æFc Balloons.h æT #define æD #define HMNamedResourceItem 1024 æC æKY HMTrackCntlItem æFc Balloons.h æT #define æD #define HMTrackCntlItem 2048 æC æKY khmmString æFc Balloons.h æT #define æD /* Constants for hmmHelpType's when filling out HMMessageRecord */ #define khmmString 1 æC æKY khmmPict æFc Balloons.h æT #define æD #define khmmPict 2 æC æKY khmmStringRes æFc Balloons.h æT #define æD #define khmmStringRes 3 æC æKY khmmTEHandle æFc Balloons.h æT #define æD #define khmmTEHandle 4 æC æKY khmmPictHandle æFc Balloons.h æT #define æD #define khmmPictHandle 5 æC æKY khmmTERes æFc Balloons.h æT #define æD #define khmmTERes 6 æC æKY khmmSTRRes æFc Balloons.h æT #define æD #define khmmSTRRes 7 æC æKY kHMEnabled æFc Balloons.h æT #define æD #define kHMEnabled 1 æC æKY kHMDisabled æFc Balloons.h æT #define æD #define kHMDisabled 2 æC æKY kHMChecked æFc Balloons.h æT #define æD #define kHMChecked 4 æC æKY kHMOther æFc Balloons.h æT #define æD #define kHMOther 8 æC æKY HMTEResType æFc Balloons.h æT #define æD /* ResTypes for Styled TE Handles when extracting from Resources */ #define HMTEResType 'thdl' æC æKY HMTEStyleType æFc Balloons.h æT #define æD #define HMTEStyleType 'tsty' æC æKY HMSTHandleType æFc Balloons.h æT #define æD #define HMSTHandleType 'tstb' æC æKY HMLHHandleType æFc Balloons.h æT #define æD #define HMLHHandleType 'thtb' æC æKY HMStringResType æFc Balloons.h æT struct æD struct HMStringResType { short hmmResID; short hmmIndex; }; typedef struct HMStringResType HMStringResType; æC æKY HMStringMsgRecord HMStringMsgRecPtr æFc Balloons.h æT struct æD struct HMStringMsgRecord { short hmmHelpType; Str255 hmmString; }; typedef struct HMStringMsgRecord HMStringMsgRecord; typedef HMStringMsgRecord *HMStringMsgRecPtr; æC æKY HMPictMsgRecord HMPictMsgRecPtr æFc Balloons.h æT struct æD struct HMPictMsgRecord { short hmmHelpType; short hmmPict; char fill[254]; }; typedef struct HMPictMsgRecord HMPictMsgRecord; typedef HMPictMsgRecord *HMPictMsgRecPtr; æC æKY HMTEHMsgRecord HMTEHMsgRecPtr æFc Balloons.h æT struct æD struct HMTEHMsgRecord { short hmmHelpType; Handle hmmTEHandle; char fill[252]; }; typedef struct HMTEHMsgRecord HMTEHMsgRecord; typedef HMTEHMsgRecord *HMTEHMsgRecPtr; æC æKY HMStrResMsgRecord HMStrResMsgRecPtr æFc Balloons.h æT struct æD struct HMStrResMsgRecord { short hmmHelpType; HMStrResType hmmStrRes; char fill[250]; }; typedef struct HMStrResMsgRecord HMStrResMsgRecord; typedef HMStrResMsgRecord *HMStrResMsgRecPtr; æC æKY HMPicHMsgRecord HMPicHMsgRecPtr æFc Balloons.h æT struct æD struct HMPicHMsgRecord { short hmmHelpType; PicHandle hmmPicHandle; char fill[252]; }; typedef struct HMPicHMsgRecord HMPicHMsgRecord; typedef HMPicHMsgRecord *HMPicHMsgRecPtr; æC æKY HMDefaultRecord HMDefaultRecPtr æFc Balloons.h æT struct æD struct HMDefaultRecord { short hmVersion; HMStringMsgRecord hmDefMessage; short hmHelpVRefNum; long hmHelpDirID; Boolean hmSearchAlternateFiles; }; typedef struct HMDefaultRecord HMDefaultRecord; typedef HMDefaultRecord *HMDefaultRecPtr; æC æKY HMStringDefaultRecord HMStringDefaultRecPtr æFc Balloons.h æT struct æD struct HMStringDefaultRecord { short hmVersion; HMStringMsgRecord hmDefMessage; short hmHelpVRefNum; long hmHelpDirID; Boolean hmSearchAlternateFiles; }; typedef struct HMStringDefaultRecord HMStringDefaultRecord; typedef HMStringDefaultRecord *HMStringDefaultRecPtr; æC æKY HMPictDefaultRecord HMPictDefaultRecPtr æFc Balloons.h æT struct æD struct HMPictDefaultRecord { short hmVersion; HMPictMsgRecord hmDefMessage; short hmHelpVRefNum; long hmHelpDirID; Boolean hmSearchAlternateFiles; }; typedef struct HMPictDefaultRecord HMPictDefaultRecord; typedef HMPictDefaultRecord *HMPictDefaultRecPtr; æC æKY HMTEHDefaultRecord HMTEHDefaultRecPtr æFc Balloons.h æT struct æD struct HMTEHDefaultRecord { short hmVersion; HMTEHMsgRecord hmDefMessage; short hmHelpVRefNum; long hmHelpDirID; Boolean hmSearchAlternateFiles; }; typedef struct HMTEHDefaultRecord HMTEHDefaultRecord; typedef HMTEHDefaultRecord *HMTEHDefaultRecPtr; æC æKY HMStrResDefaultRecord HMStrResDefaultRecPtr æFc Balloons.h æT struct æD struct HMStrResDefaultRecord { short hmVersion; HMStrResMsgRecord hmDefMessage; short hmHelpVRefNum; long hmHelpDirID; Boolean hmSearchAlternateFiles; }; typedef struct HMStrResDefaultRecord HMStrResDefaultRecord; typedef HMStrResDefaultRecord *HMStrResDefaultRecPtr; æC æKY HMPicHDefaultRecord HMPicHDefaultRecPtr æFc Balloons.h æT struct æD struct HMPicHDefaultRecord { short hmVersion; HMPicHMsgRecord hmDefMessage; short hmHelpVRefNum; long hmHelpDirID; Boolean hmSearchAlternateFiles; }; typedef struct HMPicHDefaultRecord HMPicHDefaultRecord; typedef HMPicHDefaultRecord *HMPicHDefaultRecPtr; æC æKY HMStringRecord æFc Balloons.h æT struct æD struct HMStringRecord { short hmmHelpType; short hmmFont; short hmmFontSize; char hmmMessage[256]; }; typedef struct HMStringRecord HMStringRecord; æC æKY HMMessageRecord HMMessageRecordPtr æFc Balloons.h æT struct æD union HMMessageRecord { HMStringMsgRecord HMStringMsg; HMPictMsgRecord HMPictMsg; HMTEHMsgRecord HMTEHMsg; HMStrResMsgRecord HMStrResMsg; HMResSTRMsgRecord HMResSTRMsg; HMPicHMsgRecord HMPicHMsg; }; typedef union HMMessageRecord HMMessageRecord; typedef HMMessageRecord *HMMessageRecordPtr; æC æKY HMShowBalloon æFc Balloons.h æT Function æD pascal short HMShowBalloon(const HMMessageRecord *aHelpMsg,Point tip,Rect *alternateRect, Ptr tipProc,short theProc,short variant,Boolean saveBits) = {0x303C,0x0B01,_Pack14}; æDT short myVariable = HMShowBalloon((const HMMessageRecord *) aHelpMsg,(Point) tip,(Rect *) alternateRect,() Ptr tipProc,(short) theProc,(short) variant,(Boolean) saveBits); æC If help is enabled, you can use the HMShowBalloon function to display a balloon containing the message specified by the message parameter; the balloon’s tip is located at the point specified by the tip parameter. Use the HMShowBalloon function to display a help message for an item that the user can move. Use the HMShowMenuBalloon function to display help messages for your application’s non-standard menus. Parameter Description message specifies the help message to be displayed. The HMMessageRecord data type is described in “The Help Message Record” earlier in this chapter. tip specifies, in global coordinates, the point where you want to position the balloon’s tip. For additional information about how the Help Manager positions balloons, see “How the Help Manager Positions the Help Balloon” earlier in this chapter. hotRect defines the area for which a specific help message is owned. That is, if the user moves the cursor anywhere outside the area specified by the hotRect parameter (once a balloon has been displayed), the Help Manager will remove the balloon This area is also the area of drift for the balloon tip. That is, if your specification for the tip parameter would force the Help Manager to position a balloon so that it obscures the element to be explained or so that it spills off the screen, the Help Manager attempts to relocate the tip within the area defined by the hotRect parameter. See “How the Help Manager Positions the Help Balloon” earlier in this chapter for additional information. tipProc specifies the address of a procedure you write that tests the values of the tip position and the balloon rectangle calculated by the Help Manager. You would write such a procedure if you anticipated problems positioning a help balloon. Using this function gives the application one more chance to modify the balloon’s position or dimensions before displaying it. Pass NIL for the tipProc parameter if you want the Help Manager to ignore the HMBaloonHook function. For additional information, see “Testing the Tip Position and the Dimensions of the Help Balloon” earlier in this chapter for additional information. theProc specifies the resource ID of the window definition procedure that you want the Help Manager to use to define the help balloon shape. The Help Manager reads the ‘WDEF’ resource into memory if it’s not already in memory. If the Help Manager cannot find or read the resource, the balloon is not displayed and the function returns the system error -192, resNotFound. To use the Help Manager’s default balloon shape, pass 0 for both the procedure and the variant parameter. variant specifies the variation code for the window definition procedure specified by the parameter theProc. If you specify 0 for the parameter theProc, you can still specify a value for variant to indicate a preferred tip position for the default balloon. See "Defining Your Own Balloon Shape" earlier in this chapter for additional information. saveBits a value of TRUE specifies that the Help Manager should save the bits behind the balloon. Only use the saveBits option if you are certain that the bits behind the balloon will still be valid when the balloon is removed; as would be the case, for example, with the bits behind a pulled down menu. A value of FALSE specifies that the Window Manager should generate an update event for the window behind the balloon when you remove the balloon. You must specify FALSE for saveBits if the parameter theProc is non-zero,that is, if you are defining your own balloon shape. The HMShowBalloon function returns the noErr result if the Help Manager displays a balloon. If help was disabled or if no balloon was displayed, the function returns a non-zero result. Result codes noErr 0 No error paramErr –50 Bad parameters passed in message record memFullErr –108 Not enough room in heap zone resNotFound –192 The balloon ‘WDEF’ could not be read hmHelpDisabled –850 Help is disabled hmBalloonAborted –853 Cursor was not stationary hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMRemoveBalloon æFc Balloons.h æT Function æD pascal short HMRemoveBalloon(void) = {0x303C,0x0002,_Pack14}; æDT short myVariable = HMRemoveBalloon()(void); æC The HMRemoveBalloon function removes any help message that is currently visible. If no help message is visible, the HMRemoveBalloon function does nothing. Use the HMRemoveBalloon function to remove balloons created either by HMShowBalloon or HMShowMenuBalloon. If a balloon is visible and the user disables help, the Help Manager calls this function automatically. The Help Manager also calls the HMRemoveBalloon function so that no more than one help balloon is displayed at any time. Thus if your application makes successive calls to show balloons without calling the HMRemoveBalloon function, the Help Manager calls the HMRemoveBalloon function automatically to remove the first balloon before displaying the second balloon. If your application has called the HMShowBalloon function to display a help message and the hotRect parameter was NIL, call the HMRemoveBalloon function when the cursor moves out of the specified area. In a customized 'MDEF' definition procedure, call the HMRemoveBalloon function before hiding a drawn menu. In a customized 'MBDF' procedure, call the HMRemoveBalloon function in response to the messages SaveBits and RestoreBits before saving or restoring any bits. Results codes noErr 0 No error; a balloon was removed paramErr –50 Bad parameters passed in message record hmHelpDisabled –850 Balloon help is disabled hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMGetBalloons æFc Balloons.h æT Function æD pascal Boolean HMGetBalloons(void) = {0x303C,0x0003,_Pack14}; æDT Boolean myVariable = HMGetBalloons()(void); æC The HMGetBalloons function returns the current setting of the flag parameter for the HMSetBalloons function. æKY HMSetBalloons æFc Balloons.h æT Function æD pascal Short HMSetBalloons(Boolean flag) = {0x303C,0x0104,_Pack14}; æDT Short myVariable = HMSetBalloons((Boolean) flag); æC Calling the HMSetBalloons function activates the Help Manager if the value of the flag parameter is TRUE and turns it off if the value of flag is FALSE. When help is enabled, the Help Manager automatically displays balloons for standard window parts and system dialog boxes. Disabling help removes any balloon displayed by calls to the HMShowBalloon or HMShowMenuBalloon functions. Result codes noErr 0 No error hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMShowMenuBalloon æFc Balloons.h æT Function æD pascal short HMShowMenuBalloon(short itemNum,short itemMenuID,long itemFlags, long itemReserved,Point tip,Ptr alternateRect,Ptr tipProc,short theProc, short variant) = {0x303C,0x0E05,_Pack14}; æDT short myVariable = HMShowMenuBalloon((short) itemNum,(short) itemMenuID,(long) itemFlags,() long itemReserved,(Point) tip,(Ptr) alternateRect,(Ptr) tipProc,(short) theProc,() short variant); æC The HMShowMenuBalloon function allows you to display help balloons for an application's non-standard menu. You call the HMShowMenuBalloon function from a menu’s ‘MDEF’ definition procedure right after drawing, highlighting, or determining that the cursor is over a menu item. Parameter Description itemNum specifies the number of the menu item to which the cursor is pointing. If the cursor points to the menu title, the itemNum parameter contains 0;if the cursor points to a dashed line, the itemNum parameter contains -1. itemMenuID specifies the menuID of the menu currently in use. itemFlags specifies the menu's enabledFlags Longword, which tells the Help Manager whether the menu item is enabled or disabled. The Help Manager uses this value to select the corresponding message from the ‘hmnu’ resource associated with the menu specified by itemMenuID. itemReserved reserved for future expansion; specify 0 tip specifies, in global coordinates, the point where you want the balloon’s tip. For additional information about how the Help Manager positions balloons, see “How the Help Manager Positions the Help Balloon” earlier in this chapter. hotRect specifies the area of drift for the balloon tip. That is, if your specification for the tip parameter would force the Help Manager to position a balloon so that it obscures the element to be explained or so that it spills off the screen, the Help Manager attempts to relocate the tip within the area defined by the hotRect.parameter. See “How the Help Manager Positions the Help Balloon” earlier in this chapter for additional information. tipProc specifies the address of a procedure you write that tests the values of the tip position and the balloon rectangle calculated by the Help Manager. You would write such a procedure if you anticipated problems positioning a help balloon. Using this function gives the application one more chance to modify the balloon’s position or the dimensions of the balloon before displaying it. Pass NIL for the tipProc parameter if you want the Help Manager to ignore the HMBaloonHook function. For additional information, see “Changing the Tip Position and the Dimensions of the Help Balloon” earlier in this chapter for additional information. reserved specify 0. reserved specify 0. Result codes noErr 0 No error paramErr –50 Bad parameters passed in message record memFullErr –108 Not enough room in heap zone resNotFound –192 'hmnu' resource could not be read hmHelpDisabled –850 Balloon help is disabled hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMMouseInApplRgn æFc Balloons.h æT Function æD pascal Boolean HMMouseInApplRgn(void) = {0x303C,0x0006,_Pack14}; æDT Boolean myVariable = HMMouseInApplRgn()(void); æC æKY HMIsBalloon æFc Balloons.h æT Function æD pascal Boolean HMIsBalloon(void) = {0x303C,0x0007,_Pack14}; æDT Boolean myVariable = HMIsBalloon()(void); æC The HMIsBalloon function determines whether a help balloon is currently showing. A return value of TRUE means that a balloon is showing; a value of FALSE means that no balloon is showing. æKY HMSetFont æFc Balloons.h æT Function æD pascal Short HMSetFont(short font) = {0x303C,0x0108,_Pack14}; æDT Short myVariable = HMSetFont((short) font); æC æKY HMSetFontSize æFc Balloons.h æT Function æD pascal Short HMSetFontSize(short fontsize) = {0x303C,0x0109,_Pack14}; æDT Short myVariable = HMSetFontSize((short) fontsize); æC æKY HMGetFont æFc Balloons.h æT Function æD pascal Short HMGetFont(short *font) = {0x303C,0x020A,_Pack14}; æDT Short myVariable = HMGetFont((short *) font); æC æKY HMGetFontSize æFc Balloons.h æT Function æD pascal Short HMGetFontSize(short *fontSize) = {0x303C,0x020B,_Pack14}; æDT Short myVariable = HMGetFontSize((short *) fontSize); æC æKY HMSetDialogResID æFc Balloons.h æT Function æD pascal Short HMSetDialogResID(short resID) = {0x303C,0x010C,_Pack14}; æDT Short myVariable = HMSetDialogResID((short) resID); æC You can use the HMSetDialogResID function in two ways: 1. If a dialog or alert item list ('DITL') does not include a helpItem specifying an 'hdlg' ID that the Help Manager should use to display help messages, calling the HMSetDialogResID function just before displaying the dialog or alert box tells the Help Manager to display help messages stored in the 'hdlg' resource whose ID is specified by resID. 2. If a dialog or alert item list does include a helpItem, you call the HMSetDialogResID function just before displaying the dialog or alert box to override the 'hdlg' ID resource specified in the helpItem field. Call the HMSetDialogResID function with a resID value of -1 after displaying the alert or dialog box to clear (reset) the first call. Result codes noErr 0 No error memFullErr –108 Not enough room in the heap zone resNotFound –192 'hdlg' resource could not be read hmCouldnotLoadPackage –860 There was not enough memory to load pacage hmOperationUnsupported –861 Could not interpret call æKY HMSetMenuResID æFc Balloons.h æT Function æD pascal Short HMSetMenuResID(short menuID,short resID) = {0x303C,0x020D,_Pack14}; æDT Short myVariable = HMSetMenuResID((short) menuID,(short) resID); æC The HMSetMenuResID function overrides the ‘hmnu’ resource ID used to provide help text for a particular menu. The menuID parameter specifies an existing menu ID in the application’s menu list. The resID parameter specifies a ‘hmnu’ resource ID that is to be used in place of the ‘hmnu’ resource normally used to provide help for the specified menu. If the menuID is not in the menu list, the function does nothing. To dissociate the menu specified by menuID from the resource specified by resID, specify -1 for the resID parameter. Result codes noErr 0 No error memFullErr –108 Not enough room in the heap zone resNotFound –192 'hdlg' resource could not be read hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMBalloonRect æFc Balloons.h æT Function æD pascal Short HMBalloonRect(const HMMessageRecord *aHelpMsg,Rect *coolRect) = {0x303C,0x040E,_Pack14}; æDT Short myVariable = HMBalloonRect((const HMMessageRecord *) aHelpMsg,(Rect *) coolRect); æC The HMBalloonRect function returns a rectangle in the coolRect parameter that is just the right size to display the text message specified by the aHelpMessage parameter. See “Providing Help for Application-Specific Elements” earlier in this chapter for a description of the HMMessageRecord data type. Result codes noErr 0 No Error paramErr –50 Bad parameters passed in message memFullErr –108 Not enough room in heap zone recordhmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMBaloonPict æFc Balloons.h æT Function æD pascal Short HMBaloonPict(const HMMessageRecord *aHelpMsg,Handle *coolPict) = {0x303C,0x040F,_Pack14}; æDT Short myVariable = HMBaloonPict((const HMMessageRecord *) aHelpMsg,(Handle *) coolPict); æC The HMBalloonPict function returns a handle to a picture that shows how the text contained in aHelpMessage is going to be displayed. Result codes noErr 0 No Error paramErr –50 Bad parameters passed in message memFullErr –108 Not enough room in heap zone hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMScanTemplateItems æFc Balloons.h æT Function æD pascal Short HMScanTemplateItems(Short whichID,Short whichResFile,ResType whichType) = {0x303C,0x0410,_Pack14}; æDT Short myVariable = HMScanTemplateItems((Short) whichID,(Short) whichResFile,(ResType) whichType); æC You use this function when you have no other way of associating a dialog box or window with an 'hdlg' or 'hrct' resource. This might happen because you have a dialog box with a changing title and a fixed item list or because you want to supply help for areas of a window whose title changes. When you call this function the Help Manager will provide help messages (for the frontmost window) from the resource whose type you specify with the whichType parameter and whose ID you specify using the which ID parameter. The resource must reside in the file specified by the whichResFile parameter and this file must be open. The whichType parameter specifies the type of the resource and must be either 'hdlg' or 'hrct'. Result codes noErr 0 No error fnOpenErr –38 Resource file was not open paramErr –50 Bad parameters passed in message record memFullErr –108 Not enough room in heap zone resnotFound –192 'hmnu' resource could not be read hmHelpDisabled –850 Balloon help is disabled hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMExtractHelpMsg æFc Balloons.h æT Function æD pascal Short HMExtractHelpMsg(ResType whichType,Short whichResID,Short whichMsg, Short whichState,HMMessageRecord *aHelpMsg) = {0x303C,0x0711,_Pack14}; æDT Short myVariable = HMExtractHelpMsg((ResType) whichType,(Short) whichResID,(Short) whichMsg,() Short whichState,(HMMessageRecord *) aHelpMsg); æC æKY HMFillCitationString æFc Balloons.h æT Function æD pascal Short HMFillCitationString(StringPtr origString,StringPtr stuffString, Short key) = {0x303C,0x0512,_Pack14}; æDT Short myVariable = HMFillCitationString((StringPtr) origString,(StringPtr) stuffString,() Short key); æC æKY HMGetDialogResID æFc Balloons.h æT Function æD pascal Short HMGetDialogResID(short *resID) = {0x303C,0x0213,_Pack14}; æDT Short myVariable = HMGetDialogResID((short *) resID); æC The HMGetDialogResID function returns the 'hdlg' resource ID that the Help Manager is currently using to provide help messages for a dialog box. If there is no current resource, resID contains -1. Result codes noErr 0 No error memFullErr –108 Not enough room in the heap zone resNotFound –192 'hdlg' resource could not be read hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY HMGetMenuResID æFc Balloons.h æT Function æD pascal Short HMGetMenuResID(short menuID,short *resID) = {0x303C,0x0314,_Pack14}; æDT Short myVariable = HMGetMenuResID((short) menuID,(short *) resID); æC The HMGetMenuResID function returns the ID of the 'hmnu' resource that the Help Manager is currently associating with the menu whose ID you specify for the menuID parameter. Result codes noErr 0 No error memFullErr –108 Not enough room in the heap zone resNotFound –192 'hdlg' resource could not be read hmCouldnotLoadPackage –860 There was not enough memory to load package hmOperationUnsupported –861 Could not interpret call æKY Controls.h æKL DisposeControl dragcontrol DragControl Draw1Control DrawControls findcontrol FindControl GetAuxCtl GetCRefCon GetCTitle getctitle GetCtlAction GetCtlMax GetCtlMin GetCtlValue GetCVariant GetNewControl HideControl HiliteControl KillControls MoveControl newcontrol NewControl SetCRefCon SetCTitle setctitle SetCtlAction SetCtlColor SetCtlMax SetCtlMin SetCtlValue ShowControl SizeControl testcontrol TestControl TrackControl trackcontrol UpdtControl autoTrack AuxCtlHandle AuxCtlPtr AuxCtlRec calcCntlRgn calcCRgns calcThumbRgn cBodyColor CCTabHandle CCTabPtr cFrameColor checkBoxProc ControlHandle ControlPtr ControlRecord cTextColor cThumbColor CtlCTab dispCntl dragCntl drawCntl hAxisOnly inButton inCheckBox inDownButton initCntl inLabel inMenu inPageDown inPageUp inThumb inTriangle inUpButton noConstraint popupMenuProc popupTitleCenterJust popupTitleLeftJust popupTitleRightJust posCntl pushButProc radioButProc scrollBarProc testCntl thumbCntl useWFont vAxisOnly æKY pushButProc æFc Controls.h æT #define æD #define pushButProc 0 æC æKY checkBoxProc æFc Controls.h æT #define æD #define checkBoxProc 1 æC æKY radioButProc æFc Controls.h æT #define æD #define radioButProc 2 æC æKY useWFont æFc Controls.h æT #define æD #define useWFont 8 æC æKY scrollBarProc æFc Controls.h æT #define æD #define scrollBarProc 16 æC æKY inButton æFc Controls.h æT #define æD #define inButton 10 æC æKY inCheckBox æFc Controls.h æT #define æD #define inCheckBox 11 æC æKY inUpButton æFc Controls.h æT #define æD #define inUpButton 20 æC æKY inDownButton æFc Controls.h æT #define æD #define inDownButton 21 æC æKY inPageUp æFc Controls.h æT #define æD #define inPageUp 22 æC æKY inPageDown æFc Controls.h æT #define æD #define inPageDown 23 æC æKY inThumb æFc Controls.h æT #define æD #define inThumb 129 æC æKY popupMenuProc æFc Controls.h æT #define æD #define popupMenuProc 1008 /* 63 * 16 */ æC æKY inLabel æFc Controls.h æT #define æD #define inLabel 1 æC æKY inMenu æFc Controls.h æT #define æD #define inMenu 2 æC æKY inTriangle æFc Controls.h æT #define æD #define inTriangle 4 æC æKY popupTitleLeftJust æFc Controls.h æT #define æD #define popupTitleLeftJust 0x0000 æC æKY popupTitleCenterJust æFc Controls.h æT #define æD #define popupTitleCenterJust 0x0001 æC æKY popupTitleRightJust æFc Controls.h æT #define æD #define popupTitleRightJust 0x00FF æC æKY noConstraint æFc Controls.h æT #define æD /* axis constraints for DragGrayRgn call */ #define noConstraint 0 æC æKY hAxisOnly æFc Controls.h æT #define æD #define hAxisOnly 1 æC æKY vAxisOnly æFc Controls.h æT #define æD #define vAxisOnly 2 æC æKY drawCntl æFc Controls.h æT #define æD /* control messages */ #define drawCntl 0 æC æKY testCntl æFc Controls.h æT #define æD #define testCntl 1 æC æKY calcCRgns æFc Controls.h æT #define æD #define calcCRgns 2 æC æKY initCntl æFc Controls.h æT #define æD #define initCntl 3 æC æKY dispCntl æFc Controls.h æT #define æD #define dispCntl 4 æC æKY posCntl æFc Controls.h æT #define æD #define posCntl 5 æC æKY thumbCntl æFc Controls.h æT #define æD #define thumbCntl 6 æC æKY dragCntl æFc Controls.h æT #define æD #define dragCntl 7 æC æKY autoTrack æFc Controls.h æT #define æD #define autoTrack 8 æC æKY cFrameColor æFc Controls.h æT #define æD #define cFrameColor 0 æC æKY cBodyColor æFc Controls.h æT #define æD #define cBodyColor 1 æC æKY cTextColor æFc Controls.h æT #define æD #define cTextColor 2 æC æKY cThumbColor æFc Controls.h æT #define æD #define cThumbColor 3 æC æKY calcCntlRgn æFc Controls.h æT #define æD #define calcCntlRgn 10 æC æKY calcThumbRgn æFc Controls.h æT #define æD #define calcThumbRgn 11 æC æKY ControlRecord ControlPtr ControlHandle æFc Controls.h æT struct æD struct ControlRecord { struct ControlRecord **nextControl; WindowPtr contrlOwner; Rect contrlRect; unsigned char contrlVis; unsigned char contrlHilite; short contrlValue; short contrlMin; short contrlMax; Handle contrlDefProc; Handle contrlData; ProcPtr contrlAction; long contrlRfCon; Str255 contrlTitle; }; typedef struct ControlRecord ControlRecord; typedef ControlRecord *ControlPtr, **ControlHandle; æC Every control is represented internally by a control record containing all pertinent information about that control. The control record contains the following: • A pointer to the window the control belongs to. • A handle to the next control in the window’s control list. • A handle to the control definition function. • The control’s title, if any. • A rectangle that completely encloses the control, which determines the control’s size and location within its window. The entire control, including the title of a check box or radio button, is drawn inside this rectangle. • An indication of whether the control is currently active and how it’s to be highlighted. • The current setting of the control (if this type of control retains a setting) and the minimum and maximum values the setting can assume. For check boxes and radio buttons, a setting of 0 means the control is off and 1 means it’s on. The control record also contains an indication of whether the control is currently visible or invisible. These terms refer only to whether the control is drawn in its window, not to whether you can see it on the screen. A control may be “visible” and still not appear on the screen, because it’s obscured by overlapping windows or other objects. There’s a field in the control record for a pointer to the control’s default action procedure. An action procedure defines some action to be performed repeatedly for as long as the user holds down the mouse button inside the control. The default action procedure may be used by the Control Manager function TrackControl if you call it without passing a pointer to an action procedure; this is discussed in detail in the description of TrackControl in the “Control Manager Routines” section. Finally, the control record includes a 32-bit reference value field, which is reserved for use by your application. You specify an initial reference value when you create a control, and can then read or change the reference value whenever you wish. The data type for a control record is called ControlRecord. A control record is referred to by a handle: TYPE ControlPtr = ^ControlRecord; ControlHandle = ^ControlPtr; The Control Manager functions for creating a control return a handle to a newly allocated control record; thereafter, your program should normally refer to the control by this handle. Most of the Control Manager routines expect a control handle as their first parameter. You can store into and access most of a control record’s fields with Control Manager routines, so normally you don’t have to know the exact field names. However, if you want more information about the exact structure of a control record—if you’re defining your own control types, for instance—it’s given below. _______________________________________________________________________________ »The ControlRecord Data Type The ControlRecord data type is defined as follows: TYPE ControlRecord = PACKED RECORD nextControl: ControlHandle; {next control} contrlOwner: WindowPtr; {control's window} contrlRect: Rect; {enclosing rectangle} contrlVis: Byte; {255 if visible} contrlHilite: Byte; {highlight state} contrlValue: INTEGER; {control's current setting} contrlMin: INTEGER; {control's minimum setting} contrlMax: INTEGER; {control's maximum setting} contrlDefProc: Handle; {control definition function} contrlData: Handle; {data used by contrlDefProc} contrlAction: ProcPtr; {default action procedure} contrlRfCon: LONGINT; {control's reference value} contrlTitle: Str255 {control's title} END; NextControl is a handle to the next control associated with this control’s window. All the controls belonging to a given window are kept in a linked list, beginning in the controlList field of the window record and chained together through the nextControl fields of the individual control records. The end of the list is marked by a NIL value; as new controls are created, they’re added to the beginning of the list. ContrlOwner is a pointer to the window that this control belongs to. ContrlRect is the rectangle that completely encloses the control, in the local coordinates of the control’s window. When contrlVis is 0, the control is currently invisible; when it’s 255, the control is visible. ContrlHilite specifies whether and how the control is to be highlighted, indicating whether it’s active or inactive. The HiliteControl procedure lets you set this field; see the description of HiliteControl for more information about the meaning of the field’s value. ContrlValue is the control’s current setting. For check boxes and radio buttons, 0 means the control is off and 1 means it’s on. For dials, the fields contrlMin and contrlMax define the range of possible settings; contrlValue may take on any value within that range. Other (custom) control types can use these three fields as they see fit. ContrlDefProc is a handle to the control definition function for this type of control. When you create a control, you identify its type with a control definition ID, which is converted into a handle to the control definition function and stored in the contrlDefProc field. Thereafter, the Control Manager uses this handle to access the definition function; you should never need to refer to this field directly. Note: When not running in 32-bit mode, the high-order byte of the contrlDefProc field contains some additional information that the Control Manager gets from the control definition ID; for details, see the section “Defining Your Own Controls”. ContrlData is reserved for use by the control definition function, typically to hold additional information specific to a particular control type. For example, the standard definition function for scroll bars uses this field for a handle to the region containing the scroll bar’s thumb. If no more than four bytes of additional information are needed, the definition function can store the information directly in the contrlData field rather than use a handle. ContrlAction is a pointer to the control’s default action procedure, if any. The Control Manager function TrackControl may call this procedure to respond to the user’s dragging the mouse inside the control. ContrlRfCon is the control’s reference value field, which the application may store into and access for any purpose. ContrlTitle is the control’s title, if any. æKY CtlCTab CCTabPtr CCTabHandle æFc Controls.h æT struct æD struct CtlCTab { long ccSeed; /*reserved*/ short ccRider; /*see what you have done - reserved*/ short ctSize; /*usually 3 for controls*/ ColorSpec ctTable[4]; }; typedef struct CtlCTab CtlCTab; typedef CtlCTab *CCTabPtr, **CCTabHandle; æC The contents and meaning of a control’s color table are determined by its control definition function (see “The Control Color Table Resource” section). The CTabHandle parameter used in the Color Control Manager routines provides a handle to the control color table. The components of a control color table are defined as follows: TYPE CCTabHandle = ^CCTabPtr; CCTabPtr = ^CtlCTab; CtlCTab = RECORD ccSeed: LONGINT; {not used for controls} ccRider: INTEGER; {not used for controls} ctSize: INTEGER; {number of entries in table –1} ctTable: cSpecArray {array of ColorSpec records} END; Field descriptions ccSeed The ccSeed field is unused in control color tables. ccRider The ccRider field is unused in control color tables. ctSize The ctSize field defines the number of elements in the table, minus one. For controls drawn with the standard definition procedure, this field is always 3. ctTable The ctTable field holds an array of colorSpec records. Each colorSpec is made up of a partIdentifier field and a partRGB field. The partIdentifier field holds an integer which associates an RGBColor to a particular part of the control. The definition procedures attempt to find the appropriate part identifier when preparing to draw a part. If that part identifier is not found, the first color in the table is used to draw the part. The part identifiers can appear in any order in the table. The partRGB field specifies a standard RGB color record, indicating what absolute color will be used to draw the control part found in the partIdentifier field. A standard control color table is shown in Figure 6. •••Refer to Figure 6.••• Figure 6–Control Color Table The 'cctb' resource is an exact image of this control table data structure, and is stored in the same format as 'clut' color table resources. Standard buttons, check boxes, and radio buttons use a four-element color table with part identifiers as shown below: cFrameColor (0) Frame color cBodyColor (1) Fill color for body of control cTextColor (2) Text color cThumbColor (3) Unused When highlighted, plain buttons exchange their body and text colors (colors 1 and 2); check boxes and radio buttons change their appearance without changing colors. All three types indicate deactivation by dimming their text with no change in colors. Standard scroll bars use a four-element color table with part identifiers as shown below: cFrameColor (0) Frame color, foreground color for shaft and arrows cBodyColor (1 Background color for shaft and arrows cTextColor (2) Unused cThumbColor (3) Fill color for thumb When highlighted, the arrows are filled with the foreground color (color 0) within the arrow outline. A deactivated scroll bar shows no indicator, and displays its shaft in solid background color (color 1), with no pattern. The 'cctb' resource = 0 is read into the application heap when the application starts, and serves as the default control color table. The last record in the auxiliary control list points to the default 'cctb' resource. When drawing a control, the standard control definition function searches the list for an auxiliary control record whose acOwner points to the control being drawn. If it finds such a record, it uses the color table designated by that record; if it doesn’t find one before reaching the default record at the end of the list, it uses the default color table instead. All types of controls share the same default record. The default auxiliary control record is recognized by NIL values in both its acNext and acOwner fields; the application must not change these fields. A nonstandard control definition function can use color tables of any desired size and define their contents in any way it wishes, except that part indices 1 to 127 are reserved for system definition. Any such nonstandard function should take care to bypass the defaulting mechanism just described, by allocating an explicit auxiliary record for every control it creates. æKY AuxCtlRec AuxCtlPtr AuxCtlHandle æFc Controls.h æT struct æD struct AuxCtlRec { Handle acNext; /*handle to next AuxCtlRec*/ ControlHandle acOwner; /*handle for aux record's control*/ CCTabHandle acCTable; /*color table for this control*/ short acFlags; /*misc flag byte*/ long acReserved; /*reserved for use by Apple*/ long acRefCon; /*for use by application*/ }; typedef struct AuxCtlRec AuxCtlRec; typedef AuxCtlRec *AuxCtlPtr, **AuxCtlHandle; æC The information needed for drawing controls in color is kept in a linked list of auxiliary control records, beginning in the global variable AuxCtlHead. (Notice that there is just one global list for all controls in all windows, not a separate one for each window.) Each window record has a handle to the list of controls. Figure 5 shows the auxiliary control list structure. •••Refer to Figure 5.••• Figure 5–Auxiliary Control List Each auxiliary control record is a relocatable object residing in the application heap. The most important information it holds is a handle to the control’s individual color table (see the “Control Color Tables” section). The rest of the record consists of a link to the next record in the list, a field that identifies the control’s owner, a 4-byte field reserved for future expansion, and a 4-byte reference constant for use by the application: TYPE AuxCtlHandle = ^AuxCtlPtr; AuxCtlPtr = ^AuxCtlRec; AuxCtlRec = RECORD acNext: AuxCtlHandle; {handle to next record in list} acOwner: ControlHandle; {handle to owning control} acCTable: CCTabHandle; {handle to control's color } { table} acFlags: INTEGER; {miscellaneous flags; reserved} acReserved: LONGINT; {reserved for future expansion} acRefCon: LONGINT {reserved for application use} END; Field descriptions acNext The acNext field contains a handle to the next record in the auxiliary control list. acOwner The acOwner field contains the handle of the control to which this auxiliary record belongs. Used as an ID field. acCTable The acCTable contains the handle to the control’s color table (see “Control Color Tables” below). acFlags The acFlags field contains miscellaneous flags for use by the Control Manager; this field is reserved. acReserved The acReserved field is reserved for future expansion; this must be set to 0 for future compatibility. acRefCon The acRefCon field is a reference constant for use by the application. Not every control needs an auxiliary control record. When an application is started, a resource containing a default color table is loaded from the system resource file; this resource defines a standard set of control colors. Since there is no InitControls routine, this happens when an application calls InitWindows. Separate auxiliary control records are needed only for controls whose color usage differs from the default. Each such nonstandard control must have its own auxiliary record, even if it uses the same colors as another control. This allows two or more auxiliary records to share the same control color table. If the control color table is a resource, it won’t be deleted by DisposeControl. When using an auxiliary record that is not stored as a resource, the application should not deallocate the color table if another control is still using it. A control created from scratch will initially have no auxiliary control record. If it is to use nonstandard colors, it must be given an auxiliary record and a color table with SetCtlColor (see the “Control Manager Routines” section). Such a control should normally be made invisible at creation and then displayed with ShowControl after the colors are set. For controls created from a 'CNTL' resource, the color table can be specified as a resource as well. See the section titled “The Control Color Table Resource”. A/UX systems: When using 32-bit mode. every control has its own auxiliary record. If there is no specific set of control colors for this control, the acCTable will point to the default color table. æKY NewControl æFc Controls.h æT Function æTN A954 æD pascal ControlHandle NewControl(WindowPtr theWindow,const Rect *boundsRect, const Str255 title,Boolean visible,short value,short min,short max,short procID, long refCon) = 0xA954; æDT ControlHandle myVariable = NewControl((WindowPtr) theWindow,(const Rect *) boundsRect,( const) Str255 title,(Boolean) visible,(short) value,(short) min,(short) max,(short) procID,() long refCon); æMM æRI I-319, P-112, 114, 177 æC NewControl creates a control, adds it to the beginning of theWindow’s control list, and returns a handle to the new control. The values passed as parameters are stored in the corresponding fields of the control record, as described below. The field that determines highlighting is set to 0 (no highlighting) and the pointer to the default action procedure is set to NIL (none). Note: The control definition function may do additional initialization, including changing any of the fields of the control record. The only standard control for which additional initialization is done is the scroll bar; its control definition function allocates space for a region to hold the thumb and stores the region handle in the contrlData field of the control record. TheWindow is the window the new control will belong to. All coordinates pertaining to the control will be interpreted in this window’s local coordinate system. BoundsRect, given in theWindow’s local coordinates, is the rectangle that encloses the control and thus determines its size and location. Note the following about the enclosing rectangle for the standard controls: • Simple buttons are drawn to fit the rectangle exactly. (The control definition function calls the QuickDraw procedure FrameRoundRect.) To allow for the tallest characters in the system font, there should be at least a 20-point difference between the top and bottom coordinates of the rectangle. • For check boxes and radio buttons, there should be at least a 16-point difference between the top and bottom coordinates. • By convention, scroll bars are 16 pixels wide, so there should be a 16-point difference between the left and right (or top and bottom) coordinates. (If there isn’t, the scroll bar will be scaled to fit the rectangle.) A standard scroll bar should be at least 48 pixels long, to allow room for the scroll arrows and thumb. Title is the control’s title, if any (if none, you can just pass the empty string as the title). Be sure the title will fit in the control’s enclosing rectangle; if it won’t it will be truncated on the right for check boxes and radio buttons, or centered and truncated on both ends for simple buttons. Note: Some non-Roman systems write text from right-to-left, in which case radio buttons and check boxes are drawn with their titles on the left of the control. They are also truncated on the left. See the Script Manager chapter for more information. If the visible parameter is TRUE, NewControl draws the control. Note: It does not use the standard window updating mechanism, but instead draws the control immediately in the window. The min and max parameters define the control’s range of possible settings; the value parameter gives the initial setting. For controls that don’t retain a setting, such as buttons, the values you supply for these parameters will be stored in the control record but will never be used. So it doesn’t matter what values you give for those controls—0 for all three parameters will do. For controls that just retain an on-or-off setting, such as check boxes or radio buttons, min should be 0 (meaning the control is off) and max should be 1 (meaning it’s on). For dials, you can specify whatever values are appropriate for min, max, and value. ProcID is the control definition ID, which leads to the control definition function for this type of control. (The function is read into memory if it isn’t already in memory.) The control definition IDs for the standard control types are listed above under “Controls and Resources”. Control definition IDs for custom control types are discussed later under “Defining Your Own Controls”. RefCon is the control’s reference value, set and used only by your application. æKY SetCTitle æFc Controls.h æT Function æTN A95F æD pascal void SetCTitle(ControlHandle theControl,const Str255 title) = 0xA95F; æDT SetCTitle((ControlHandle) theControl,(const Str255) title); æMM æRI I-321 æC SetCTitle sets theControl’s title to the given string and redraws the control. æKY GetCTitle æFc Controls.h æT Function æTN A95E æD pascal void GetCTitle(ControlHandle theControl,Str255 title) = 0xA95E; æDT GetCTitle((ControlHandle) theControl,(Str255) title); æRI I-321 æC GetCTitle returns theControl’s title as the value of the title parameter. æKY GetNewControl æFc Controls.h æT Function æTN A9BE æD pascal ControlHandle GetNewControl(short controlID,WindowPtr owner) = 0xA9BE; æDT ControlHandle myVariable = GetNewControl((short) controlID,(WindowPtr) owner); æMM æRT 203 æRI I-321, P-112, 113, 114, 172 æC GetNewControl creates a control from a control template stored in a resource file, adds it to the beginning of theWindow’s control list, and returns a handle to the new control. ControlID is the resource ID of the template. GetNewControl works exactly the same as NewControl (above), except that it gets the initial values for the new control’s fields from the specified control template instead of accepting them as parameters. If the control template can’t be read from the resource file, GetNewControl returns NIL. It releases the memory occupied by the resource before returning. The system default control colors are stored in the System file and ROMResources as 'cctb' resource = 0. By including a 'cctb' resource = 0 in your application, it is possible to change the default colors that will be used for all controls, unless a specific 'cctb' exists for a control defined within the application. When you use GetNewControl for the control resource 'CNTL', GetNewControl will attempt to load a 'cctb' resource with the same ID as the 'CNTL' resource ID, if one is present. It then executes the SetCtlColor call. The following part identifiers for control elements should be present in the ColorSpec.value field: cFrameColor (0) Frame color cBodyColor (1) Fill color for body of control cTextColor (2) Text color cThumbColor (3) Thumb color These identifiers may be present in any order; for instance, the text or indicator color values may be stored before the fill and frame colors in the ColorSpec record structure. If a part identifier is not found, then the first color in the color table will be used. æKY DisposeControl æFc Controls.h æT Function æTN A955 æD pascal void DisposeControl(ControlHandle theControl) = 0xA955; æDT DisposeControl((ControlHandle) theControl); æMM æRI I-321, P-168 æC Assembly-language note: The macro you invoke to call DisposeControl from assembly language is named _DisposControl. DisposeControl removes theControl from the screen, deletes it from its window’s control list, and releases the memory occupied by the control record and any data structures associated with the control. æKY KillControls æFc Controls.h æT Function æTN A956 æD pascal void KillControls(WindowPtr theWindow) = 0xA956; æDT KillControls((WindowPtr) theWindow); æMM æRI I-321, P-113, 175 æC KillControls disposes of all controls associated with theWindow by calling DisposeControl (above) for each. Note: Remember that the Window Manager procedures CloseWindow and DisposeWindow automatically dispose of all controls associated with the given window. æKY HideControl æFc Controls.h æT Function æTN A958 æD pascal void HideControl(ControlHandle theControl) = 0xA958; æDT HideControl((ControlHandle) theControl); æMM æRI I-322, P-113, 114, 174 æC HideControl makes theControl invisible. It fills the region the control occupies within its window with the background pattern of the window’s grafPort. It also adds the control’s enclosing rectangle to the window’s update region, so that anything else that was previously obscured by the control will reappear on the screen. If the control is already invisible, HideControl has no effect. æKY ShowControl æFc Controls.h æT Function æTN A957 æD pascal void ShowControl(ControlHandle theControl) = 0xA957; æDT ShowControl((ControlHandle) theControl); æMM æRT 197 æRI I-322, P-113, 114, 181 æC ShowControl makes theControl visible. The control is drawn in its window but may be completely or partially obscured by overlapping windows or other objects. If the control is already visible, ShowControl has no effect. æKY DrawControls æFc Controls.h æT Function æTN A969 æD pascal void DrawControls(WindowPtr theWindow) = 0xA969; æDT DrawControls((WindowPtr) theWindow); æRT 203 æRI I-322, P-169 æC DrawControls draws all controls currently visible in theWindow. The controls are drawn in reverse order of creation; thus in case of overlap the earliest-created controls appear frontmost in the window. Note: Window Manager routines such as SelectWindow, ShowWindow, and BringToFront do not automatically call DrawControls to display the window’s controls. They just add the appropriate regions to the window’s update region, generating an update event. Your program should always call DrawControls explicitly upon receiving an update event for a window that contains controls. æKY Draw1Control æFc Controls.h æT Function æTN A96D æD pascal void Draw1Control(ControlHandle theControl) = 0xA96D; æDT Draw1Control((ControlHandle) theControl); æMM æRI IV-53 æC [128K ROM] Draw1Control draws the specified control if it’s visible within the window. æKY HiliteControl æFc Controls.h æT Function æTN A95D æD pascal void HiliteControl(ControlHandle theControl,short hiliteState) = 0xA95D; æDT HiliteControl((ControlHandle) theControl,(short) hiliteState); æMM æRI I-322 æC HiliteControl changes the way theControl is highlighted. HiliteState has one of the following values: • The value 0 means no highlighting. (The control is active.) • A value between 1 and 253 is interpreted as a part code designating the part of the (active) control to be highlighted. • The value 255 means that the control is to be made inactive and highlighted accordingly. Note: The value 254 should not be used; this value is reserved for future use. HiliteControl calls the control definition function to redraw the control with its new highlighting. æKY UpdtControl æFc Controls.h æT Function æTN A953 æD pascal void UpdtControl(WindowPtr theWindow,RgnHandle updateRgn) = 0xA953; æDT UpdtControl((WindowPtr) theWindow,(RgnHandle) updateRgn); æMM æRI IV-53 æC [128K ROM] UpdtControl is a faster version of the DrawControls procedure. Instead of drawing all of the controls in theWindow, UpdtControl draws only the controls that are in the specified update region. UpdtControl is called in response to an update event, and is usually bracketed by calls to the Window Manager procedures BeginUpdate and EndUpdate. UpdateRgn should be set to the visRgn of theWindow’s port (for more details, see the BeginUpdate procedure in the Window Manager chapter). Note: In general, controls are in a dialog box and are automatically drawn by the DrawDialog procedure. æKY MoveControl æFc Controls.h æT Function æTN A959 æD pascal void MoveControl(ControlHandle theControl,short h,short v) = 0xA959; æDT MoveControl((ControlHandle) theControl,(short) h,(short) v); æMM æRI I-325, P-113, 176 æC MoveControl moves theControl to a new location within its window. The top left corner of the control’s enclosing rectangle is moved to the horizontal and vertical coordinates h and v (given in the local coordinates of the control’s window); the bottom right corner is adjusted accordingly, to keep the size of the rectangle the same as before. If the control is currently visible, it’s hidden and then redrawn at its new location. æKY SizeControl æFc Controls.h æT Function æTN A95C æD pascal void SizeControl(ControlHandle theControl,short w,short h) = 0xA95C; æDT SizeControl((ControlHandle) theControl,(short) w,(short) h); æMM æRI I-326, P-113, 181 æC SizeControl changes the size of theControl’s enclosing rectangle. The bottom right corner of the rectangle is adjusted to set the rectangle’s width and height to the number of pixels specified by w and h; the position of the top left corner is not changed. If the control is currently visible, it’s hidden and then redrawn in its new size. æKY SetCtlValue æFc Controls.h æT Function æTN A963 æD pascal void SetCtlValue(ControlHandle theControl,short theValue) = 0xA963; æDT SetCtlValue((ControlHandle) theControl,(short) theValue); æMM æRT 197 æRI I-326 æC SetCtlValue sets theControl’s current setting to theValue and redraws the control to reflect the new setting. For check boxes and radio buttons, the value 1 fills the control with the appropriate mark, and 0 clears it. For scroll bars, SetCtlValue redraws the thumb where appropriate. If the specified value is out of range, it’s forced to the nearest endpoint of the current range (that is, if theValue is less than the minimum setting, SetCtlValue sets the current setting to the minimum; if theValue is greater than the maximum setting, it sets the current setting to the maximum). æKY GetCtlValue æFc Controls.h æT Function æTN A960 æD pascal short GetCtlValue(ControlHandle theControl) = 0xA960; æDT short myVariable = GetCtlValue((ControlHandle) theControl); æRI I-326, P-114, 171 æC GetCtlValue returns theControl’s current setting. æKY SetCtlMin æFc Controls.h æT Function æTN A964 æD pascal void SetCtlMin(ControlHandle theControl,short minValue) = 0xA964; æDT SetCtlMin((ControlHandle) theControl,(short) minValue); æMM æRI I-326 æC Assembly-language note: The macro you invoke to call SetCtlMin from assembly language is named _SetMinCtl. SetCtlMin sets theControl’s minimum setting to minValue and redraws the control to reflect the new range. If the control’s current setting is less than minValue, the setting is changed to the new minimum. æKY GetCtlMin æFc Controls.h æT Function æTN A961 æD pascal short GetCtlMin(ControlHandle theControl) = 0xA961; æDT short myVariable = GetCtlMin((ControlHandle) theControl); æRI I-327 æC Assembly-language note: The macro you invoke to call GetCtlMin from assembly language is named _GetMinCtl. GetCtlMin returns theControl’s minimum setting. æKY SetCtlMax æFc Controls.h æT Function æTN A965 æD pascal void SetCtlMax(ControlHandle theControl,short maxValue) = 0xA965; æDT SetCtlMax((ControlHandle) theControl,(short) maxValue); æMM æRI I-327 æC Assembly-language note: The macro you invoke to call SetCtlMax from assembly language is named _SetMaxCtl. SetCtlMax sets theControl’s maximum setting to maxValue and redraws the control to reflect the new range. If the control’s current setting is greater than maxValue, the setting is changed to the new maximum. Note: If you set the maximum setting of a scroll bar equal to its minimum setting, the control definition function will make the scroll bar inactive. æKY GetCtlMax æFc Controls.h æT Function æTN A962 æD pascal short GetCtlMax(ControlHandle theControl) = 0xA962; æDT short myVariable = GetCtlMax((ControlHandle) theControl); æRI I-327 æC Assembly-language note: The macro you invoke to call GetCtlMax from assembly language is named _GetMaxCtl. GetCtlMax returns theControl’s maximum setting. æKY SetCRefCon æFc Controls.h æT Function æTN A95B æD pascal void SetCRefCon(ControlHandle theControl,long data) = 0xA95B; æDT SetCRefCon((ControlHandle) theControl,(long) data); æRI I-327 æC SetCRefCon sets theControl’s reference value to the given data. æKY GetCRefCon æFc Controls.h æT Function æTN A95A æD pascal long GetCRefCon(ControlHandle theControl) = 0xA95A; æDT long myVariable = GetCRefCon((ControlHandle) theControl); æRI I-327 æC GetCRefCon returns theControl’s current reference value. æKY SetCtlAction æFc Controls.h æT Function æTN A96B æD pascal void SetCtlAction(ControlHandle theControl,ProcPtr actionProc) = 0xA96B; æDT SetCtlAction((ControlHandle) theControl,(ProcPtr) actionProc); æRI I-328 æC SetCtlAction sets theControl’s default action procedure to actionProc. æKY GetCtlAction æFc Controls.h æT Function æTN A96A æD pascal ProcPtr GetCtlAction(ControlHandle theControl) = 0xA96A; æDT ProcPtr myVariable = GetCtlAction((ControlHandle) theControl); æRI I-328, IV-53 æC GetCtlAction returns a pointer to theControl’s default action procedure, if any. (It returns whatever is in that field of the control record.) æKY DragControl æFc Controls.h æT Function æTN A967 æD pascal void DragControl(ControlHandle theControl,Point startPt,const Rect *limitRect, const Rect *slopRect,short axis) = 0xA967; æDT DragControl((ControlHandle) theControl,(Point) startPt,(const Rect *) limitRect,( const Rect) * slopRect,(short) axis); æMM æRI I-325 æC Called with the mouse button down inside theControl, DragControl pulls a dotted outline of the control around the screen, following the movements of the mouse until the button is released. When the mouse button is released, DragControl calls MoveControl to move the control to the location to which it was dragged. Note: Before beginning to follow the mouse, DragControl calls the control definition function to allow it to do its own “custom dragging” if it chooses. If the definition function doesn’t choose to do any custom dragging, DragControl uses the default method of dragging described here. The startPt, limitRect, slopRect, and axis parameters have the same meaning as for the Window Manager function DragGrayRgn. These parameters are reviewed briefly below; see the description of DragGrayRgn in the Window Manager chapter for more details. • StartPt is assumed to be the point where the mouse button was originally pressed, in the local coordinates of the control’s window. • LimitRect limits the travel of the control’s outline, and should normally coincide with or be contained within the window’s content region. • SlopRect allows the user some “slop” in moving the mouse; it should completely enclose limitRect. • The axis parameter allows you to constrain the control’s motion to only one axis. It has one of the following values: CONST noConstraint = 0; {no constraint} hAxisOnly = 1; {horizontal axis only} vAxisOnly = 2; {vertical axis only} Assembly-language note: Like TrackControl, DragControl invokes the macro _DragTheRgn, so you can use the global variables DragHook and DragPattern. æKY TestControl æFc Controls.h æT Function æTN A966 æD pascal short TestControl(ControlHandle theControl,Point thePt) = 0xA966; æDT short myVariable = TestControl((ControlHandle) theControl,(Point) thePt); æMM æRI I-325 æC If theControl is visible and active, TestControl tests which part of the control contains thePoint (in the local coordinates of the control’s window); it returns the corresponding part code, or 0 if the point is outside the control. If the control is invisible or inactive, TestControl returns 0. TestControl is called by FindControl and TrackControl; normally you won’t need to call it yourself. æKY TrackControl æFc Controls.h æT Function æTN A968 æD pascal short TrackControl(ControlHandle theControl,Point thePoint,ProcPtr actionProc) = 0xA968; æDT short myVariable = TrackControl((ControlHandle) theControl,(Point) thePoint,(ProcPtr) actionProc); æMM æRI I-323, P-114, 184 æC When the mouse button is pressed in a visible, active control, the application should call TrackControl with theControl equal to the control handle and startPt equal to the point where the mouse button was pressed (in the local coordinates of the control’s window). TrackControl follows the movements of the mouse and responds in whatever way is appropriate until the mouse button is released; the exact response depends on the type of control and the part of the control in which the mouse button was pressed. If highlighting is appropriate, TrackControl does the highlighting, and undoes it before returning. When the mouse button is released, TrackControl returns with the part code if the mouse is in the same part of the control that it was originally in, or with 0 if not (in which case the application should do nothing). If the mouse button was pressed in an indicator, TrackControl drags a dotted outline of it to follow the mouse. When the mouse button is released, TrackControl calls the control definition function to reposition the control’s indicator. The control definition function for scroll bars responds by redrawing the thumb, calculating the control’s current setting based on the new relative position of the thumb, and storing the current setting in the control record; for example, if the minimum and maximum settings are 0 and 10, and the thumb is in the middle of the scroll bar, 5 is stored as the current setting. The application must then scroll to the corresponding relative position in the document. TrackControl may take additional actions beyond highlighting the control or dragging the indicator, depending on the value passed in the actionProc parameter, as described below. The following tells you what to pass for the standard control types; for a custom control, what you pass will depend on how the control is defined. • If actionProc is NIL, TrackControl performs no additional actions. This is appropriate for simple buttons, check boxes, radio buttons, and the thumb of a scroll bar. • ActionProc may be a pointer to an action procedure that defines some action to be performed repeatedly for as long as the user holds down the mouse button. (See below for details.) • If actionProc is POINTER(–1), TrackControl looks in the control record for a pointer to the control’s default action procedure. If that field of the control record contains a procedure pointer, TrackControl uses the action procedure it points to; if the field contains POINTER (–1), TrackControl calls the control definition function to perform the necessary action. (If the field contains NIL, TrackControl does nothing.) The action procedure in the control definition function is described in the section “Defining Your Own Controls”. The following paragraphs describe only the action procedure whose pointer is passed in the actionProc parameter or stored in the control record. If the mouse button was pressed in an indicator, the action procedure (if any) should have no parameters. This procedure must allow for the fact that the mouse may not be inside the original control part. If the mouse button was pressed in a control part other than an indicator, the action procedure should be of the form PROCEDURE MyAction (theControl: ControlHandle; partCode: INTEGER); In this case, TrackControl passes the control handle and the part code to the action procedure. (It passes 0 in the partCode parameter if the mouse has moved outside the original control part.) As an example of this type of action procedure, consider what should happen when the mouse button is pressed in a scroll arrow or paging region in a scroll bar. For these cases, your action procedure should examine the part code to determine exactly where the mouse button was pressed, scroll up or down a line or page as appropriate, and call SetCtlValue to change the control’s setting and redraw the thumb. Warning: Since it has a different number of parameters depending on whether the mouse button was pressed in an indicator or elsewhere, the action procedure you pass to TrackControl (or whose pointer you store in the control record) can be set up for only one case or the other. If you store a pointer to a default action procedure in a control record, be sure it will be used only when appropriate for that type of action procedure. The only way to specify actions in response to all mouse-down events in a control, regardless of whether they’re in an indicator, is via the control definition function. Assembly-language note: If you store a pointer to a procedure in the global variable DragHook, that procedure will be called repeatedly (with no parameters) for as long as the user holds down the mouse button. TrackControl invokes the Window Manager macro _DragTheRgn, which calls the DragHook procedure. _DragTheRgn uses the pattern stored in the global variable DragPattern for the dragged outline of the indicator. æKY FindControl æFc Controls.h æT Function æTN A96C æD pascal short FindControl(Point thePoint,WindowPtr theWindow,ControlHandle *theControl) = 0xA96C; æDT short myVariable = FindControl((Point) thePoint,(WindowPtr) theWindow,(ControlHandle *) theControl); æMM æRI I-323, P-98, 114, 170 æC When the Window Manager function FindWindow reports that the mouse button was pressed in the content region of a window, and the window contains controls, the application should call FindControl with theWindow equal to the window pointer and thePoint equal to the point where the mouse button was pressed (in the window’s local coordinates). FindControl tells which of the window’s controls, if any, the mouse button was pressed in: • If it was pressed in a visible, active control, FindControl sets the whichControl parameter to the control handle and returns a part code identifying the part of the control that it was pressed in. • If it was pressed in an invisible or inactive control, or not in any control, FindControl sets whichControl to NIL and returns 0 as its result. Warning: Notice that FindControl expects the mouse point in the window’s local coordinates, whereas FindWindow expects it in global coordinates. Always be sure to convert the point to local coordinates with the QuickDraw procedure GlobalToLocal before calling FindControl. Note: FindControl also returns NIL for whichControl and 0 as its result if the window is invisible or doesn’t contain the given point. In these cases, however, FindWindow wouldn’t have returned this window in the first place, so the situation should never arise. æKY SetCtlColor æFc Controls.h æT Function æTN AA43 æD pascal void SetCtlColor(ControlHandle theControl,CCTabHandle newColorTable) = 0xAA43; æDT SetCtlColor((ControlHandle) theControl,(CCTabHandle) newColorTable); æMM æRI V-222 æC [Macintosh II] The SetCtlColor procedure sets or modifies a control’s color table. If the control currently has no auxiliary control record, a new one is created with the given color table and added to the head of the auxiliary control list. If there is already an auxiliary record for the control, its color table is replaced by the contents of newColorTable. If newColorTable has the same contents as the default color table, the control’s existing auxiliary record and color table are removed from the auxiliary control list and deallocated. If theControl = NIL, the operation modifies the default color table itself. If the control is visible, it will be redrawn by SetCtlColor using the new color table. æKY GetAuxCtl æFc Controls.h æT Function æTN AA44 æD pascal Boolean GetAuxCtl(ControlHandle theControl,AuxCtlHandle *acHndl) = 0xAA44; æDT Boolean myVariable = GetAuxCtl((ControlHandle) theControl,(AuxCtlHandle *) acHndl); æMM æRI V-222 æC [Macintosh II] The GetAuxCtl function returns a handle to a control’s AuxCtlRec: • If the given control has its own color table, the function returns TRUE. • If the control used the default color set, the function returns FALSE. • If the control asked to receive the default color set (theControl = NIL), then the function returns TRUE. æKY GetCVariant æFc Controls.h æT Function æTN A809 æD pascal short GetCVariant(ControlHandle theControl) = 0xA809; æDT short myVariable = GetCVariant((ControlHandle) theControl); æRI V-222 æC [Macintosh Plus, Macintosh SE, and Macintosh II] The GetVariant function returns the variant control value for the control described by theControl. This value was formerly stored in the high four bits of the control defproc handle; for future compatibility, use the GetCVariant routine to access this value. æKY dragcontrol æFc Controls.h æT Function æD void dragcontrol(ControlHandle theControl,Point *startPt,const Rect *limitRect, const Rect *slopRect,short axis); æDT dragcontrol((ControlHandle) theControl,(Point *) startPt,(const Rect *) limitRect,( const Rect) * slopRect,(short) axis); æMM æRI I-325 æC Called with the mouse button down inside theControl, DragControl pulls a dotted outline of the control around the screen, following the movements of the mouse until the button is released. When the mouse button is released, DragControl calls MoveControl to move the control to the location to which it was dragged. Note: Before beginning to follow the mouse, DragControl calls the control definition function to allow it to do its own “custom dragging” if it chooses. If the definition function doesn’t choose to do any custom dragging, DragControl uses the default method of dragging described here. The startPt, limitRect, slopRect, and axis parameters have the same meaning as for the Window Manager function DragGrayRgn. These parameters are reviewed briefly below; see the description of DragGrayRgn in the Window Manager chapter for more details. • StartPt is assumed to be the point where the mouse button was originally pressed, in the local coordinates of the control’s window. • LimitRect limits the travel of the control’s outline, and should normally coincide with or be contained within the window’s content region. • SlopRect allows the user some “slop” in moving the mouse; it should completely enclose limitRect. • The axis parameter allows you to constrain the control’s motion to only one axis. It has one of the following values: CONST noConstraint = 0; {no constraint} hAxisOnly = 1; {horizontal axis only} vAxisOnly = 2; {vertical axis only} Assembly-language note: Like TrackControl, DragControl invokes the macro _DragTheRgn, so you can use the global variables DragHook and DragPattern. æKY newcontrol æFc Controls.h æT Function æTN A954 æD ControlHandle newcontrol(WindowPtr theWindow,const Rect *boundsRect,char *title, Boolean visible,short value,short min,short max,short procID,long refCon); æDT ControlHandle myVariable = newcontrol((WindowPtr) theWindow,(const Rect *) boundsRect,(char *) title,() Boolean visible,(short) value,(short) min,(short) max,(short) procID,(long) refCon); æMM æRI I-319, P-112, 114, 177 æC NewControl creates a control, adds it to the beginning of theWindow’s control list, and returns a handle to the new control. The values passed as parameters are stored in the corresponding fields of the control record, as described below. The field that determines highlighting is set to 0 (no highlighting) and the pointer to the default action procedure is set to NIL (none). Note: The control definition function may do additional initialization, including changing any of the fields of the control record. The only standard control for which additional initialization is done is the scroll bar; its control definition function allocates space for a region to hold the thumb and stores the region handle in the contrlData field of the control record. TheWindow is the window the new control will belong to. All coordinates pertaining to the control will be interpreted in this window’s local coordinate system. BoundsRect, given in theWindow’s local coordinates, is the rectangle that encloses the control and thus determines its size and location. Note the following about the enclosing rectangle for the standard controls: • Simple buttons are drawn to fit the rectangle exactly. (The control definition function calls the QuickDraw procedure FrameRoundRect.) To allow for the tallest characters in the system font, there should be at least a 20-point difference between the top and bottom coordinates of the rectangle. • For check boxes and radio buttons, there should be at least a 16-point difference between the top and bottom coordinates. • By convention, scroll bars are 16 pixels wide, so there should be a 16-point difference between the left and right (or top and bottom) coordinates. (If there isn’t, the scroll bar will be scaled to fit the rectangle.) A standard scroll bar should be at least 48 pixels long, to allow room for the scroll arrows and thumb. Title is the control’s title, if any (if none, you can just pass the empty string as the title). Be sure the title will fit in the control’s enclosing rectangle; if it won’t it will be truncated on the right for check boxes and radio buttons, or centered and truncated on both ends for simple buttons. Note: Some non-Roman systems write text from right-to-left, in which case radio buttons and check boxes are drawn with their titles on the left of the control. They are also truncated on the left. See the Script Manager chapter for more information. If the visible parameter is TRUE, NewControl draws the control. Note: It does not use the standard window updating mechanism, but instead draws the control immediately in the window. The min and max parameters define the control’s range of possible settings; the value parameter gives the initial setting. For controls that don’t retain a setting, such as buttons, the values you supply for these parameters will be stored in the control record but will never be used. So it doesn’t matter what values you give for those controls—0 for all three parameters will do. For controls that just retain an on-or-off setting, such as check boxes or radio buttons, min should be 0 (meaning the control is off) and max should be 1 (meaning it’s on). For dials, you can specify whatever values are appropriate for min, max, and value. ProcID is the control definition ID, which leads to the control definition function for this type of control. (The function is read into memory if it isn’t already in memory.) The control definition IDs for the standard control types are listed above under “Controls and Resources”. Control definition IDs for custom control types are discussed later under “Defining Your Own Controls”. RefCon is the control’s reference value, set and used only by your application. æKY findcontrol æFc Controls.h æT Function æD short findcontrol(Point *thePoint,WindowPtr theWindow,ControlHandle *theControl); æDT short myVariable = findcontrol((Point *) thePoint,(WindowPtr) theWindow,(ControlHandle *) theControl); æMM æRI I-323, P-98, 114, 170 æC When the Window Manager function FindWindow reports that the mouse button was pressed in the content region of a window, and the window contains controls, the application should call FindControl with theWindow equal to the window pointer and thePoint equal to the point where the mouse button was pressed (in the window’s local coordinates). FindControl tells which of the window’s controls, if any, the mouse button was pressed in: • If it was pressed in a visible, active control, FindControl sets the whichControl parameter to the control handle and returns a part code identifying the part of the control that it was pressed in. • If it was pressed in an invisible or inactive control, or not in any control, FindControl sets whichControl to NIL and returns 0 as its result. Warning: Notice that FindControl expects the mouse point in the window’s local coordinates, whereas FindWindow expects it in global coordinates. Always be sure to convert the point to local coordinates with the QuickDraw procedure GlobalToLocal before calling FindControl. Note: FindControl also returns NIL for whichControl and 0 as its result if the window is invisible or doesn’t contain the given point. In these cases, however, FindWindow wouldn’t have returned this window in the first place, so the situation should never arise. æKY getctitle æFc Controls.h æT Function æD void getctitle(ControlHandle theControl,char *title); æDT getctitle((ControlHandle) theControl,(char *) title); æRI I-321 æC GetCTitle returns theControl’s title as the value of the title parameter. æKY setctitle æFc Controls.h æT Function æD void setctitle(ControlHandle theControl,char *title); æDT setctitle((ControlHandle) theControl,(char *) title); æMM æRI I-321 æC SetCTitle sets theControl’s title to the given string and redraws the control. æKY trackcontrol æFc Controls.h æT Function æD short trackcontrol(ControlHandle theControl,Point *thePoint,ProcPtr actionProc); æDT short myVariable = trackcontrol((ControlHandle) theControl,(Point *) thePoint,(ProcPtr) actionProc); æMM æRI I-323, P-114, 184 æC When the mouse button is pressed in a visible, active control, the application should call TrackControl with theControl equal to the control handle and startPt equal to the point where the mouse button was pressed (in the local coordinates of the control’s window). TrackControl follows the movements of the mouse and responds in whatever way is appropriate until the mouse button is released; the exact response depends on the type of control and the part of the control in which the mouse button was pressed. If highlighting is appropriate, TrackControl does the highlighting, and undoes it before returning. When the mouse button is released, TrackControl returns with the part code if the mouse is in the same part of the control that it was originally in, or with 0 if not (in which case the application should do nothing). If the mouse button was pressed in an indicator, TrackControl drags a dotted outline of it to follow the mouse. When the mouse button is released, TrackControl calls the control definition function to reposition the control’s indicator. The control definition function for scroll bars responds by redrawing the thumb, calculating the control’s current setting based on the new relative position of the thumb, and storing the current setting in the control record; for example, if the minimum and maximum settings are 0 and 10, and the thumb is in the middle of the scroll bar, 5 is stored as the current setting. The application must then scroll to the corresponding relative position in the document. TrackControl may take additional actions beyond highlighting the control or dragging the indicator, depending on the value passed in the actionProc parameter, as described below. The following tells you what to pass for the standard control types; for a custom control, what you pass will depend on how the control is defined. • If actionProc is NIL, TrackControl performs no additional actions. This is appropriate for simple buttons, check boxes, radio buttons, and the thumb of a scroll bar. • ActionProc may be a pointer to an action procedure that defines some action to be performed repeatedly for as long as the user holds down the mouse button. (See below for details.) • If actionProc is POINTER(–1), TrackControl looks in the control record for a pointer to the control’s default action procedure. If that field of the control record contains a procedure pointer, TrackControl uses the action procedure it points to; if the field contains POINTER (–1), TrackControl calls the control definition function to perform the necessary action. (If the field contains NIL, TrackControl does nothing.) The action procedure in the control definition function is described in the section “Defining Your Own Controls”. The following paragraphs describe only the action procedure whose pointer is passed in the actionProc parameter or stored in the control record. If the mouse button was pressed in an indicator, the action procedure (if any) should have no parameters. This procedure must allow for the fact that the mouse may not be inside the original control part. If the mouse button was pressed in a control part other than an indicator, the action procedure should be of the form PROCEDURE MyAction (theControl: ControlHandle; partCode: INTEGER); In this case, TrackControl passes the control handle and the part code to the action procedure. (It passes 0 in the partCode parameter if the mouse has moved outside the original control part.) As an example of this type of action procedure, consider what should happen when the mouse button is pressed in a scroll arrow or paging region in a scroll bar. For these cases, your action procedure should examine the part code to determine exactly where the mouse button was pressed, scroll up or down a line or page as appropriate, and call SetCtlValue to change the control’s setting and redraw the thumb. Warning: Since it has a different number of parameters depending on whether the mouse button was pressed in an indicator or elsewhere, the action procedure you pass to TrackControl (or whose pointer you store in the control record) can be set up for only one case or the other. If you store a pointer to a default action procedure in a control record, be sure it will be used only when appropriate for that type of action procedure. The only way to specify actions in response to all mouse-down events in a control, regardless of whether they’re in an indicator, is via the control definition function. Assembly-language note: If you store a pointer to a procedure in the global variable DragHook, that procedure will be called repeatedly (with no parameters) for as long as the user holds down the mouse button. TrackControl invokes the Window Manager macro _DragTheRgn, which calls the DragHook procedure. _DragTheRgn uses the pattern stored in the global variable DragPattern for the dragged outline of the indicator. æKY testcontrol æFc Controls.h æT Function æD short testcontrol(ControlHandle theControl,Point *thePt); æDT short myVariable = testcontrol((ControlHandle) theControl,(Point *) thePt); æMM æRI I-325 æC If theControl is visible and active, TestControl tests which part of the control contains thePoint (in the local coordinates of the control’s window); it returns the corresponding part code, or 0 if the point is outside the control. If the control is invisible or inactive, TestControl returns 0. TestControl is called by FindControl and TrackControl; normally you won’t need to call it yourself. æKY Ctype.h æKL _tolower _toupper isalnum isalpha isascii iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit toascii tolower toupper æKY isalpha isupper islower isdigit isxdigit isalnum isspace ispunct isprint isgraph iscntrl isascii æFc CType.h æC These functions tell whether a given character is in one of several categories: alphabetical, uppercase, lowercase, digit, hex digit, white-space, punctuation mark, printing, graphic, or control. A separate function is provided for each category. Synopsis #include <CType.h> int isalpha(int c); int isupper(int c); int islower(int c); int isdigit(int c); int isxdigit(int c); int isalnum(int c); int isspace(int c); int ispunct(int c); int isprint(int c); int isgraph(int c); int iscntrl(int c); int isascii(int c); Description These macros return nonzero for true, zero for false, depending on the corresponding integer value of the given character. The isascii macro is defined on all integer values; the rest are defined only where isascii is true and on the single non-ASCII value EOF(–1). Table 3-1 shows when these macros return the value true. Table 3-1 Character-testing macros Macro Returns true if isascii; c is an ASCII character code lower than128. isalpha; c is a letter [A–Z] or [a–z]. isupper; c is an uppercase letter [A–Z]. islower; c is a lowercase letter [a–z]. isdigit; c is a digit [0–9]. isxdigit; c is a hexadecimal digit [0–9], [A–F], or [a–f]. isalnum; c is alphanumeric (letter or digit). isspace; c is a space, tab, return, new line, vertical tab, or form feed. ispunct; c is a punctuation character (neither control nor alphanumeric). isprint; c is a printing character, space (32) through tilde (126). isgraph; c is a printing character, similar to isprint except false for space. iscntrl; c is a delete character (127) or an ordinary control character (less than 32). Note These macros do not support the Macintosh extended character set. For values outside the domain, the result is undefined. Warning If c is not in the domain of the function, the result is undefined. See also Character case æKY toupper tolower _toupper _tolower toascii æFc CType.h æC The first four of these routines change the case of a character. The toascii function converts any character to an ASCII character. Synopsis #include <CType.h> int toupper(int c); int tolower(int c); int _toupper(int c); int _tolower(int c); int toascii(int c); Description The toupper; and tolower; functions have as their domain the set of ASCII characters (0 through 127) and the constant EOF (– 1). If parameter c to toupper represents a lowercase letter, the result is the corresponding uppercase letter. If parameter c to tolower represents an uppercase letter, the result is the corresponding lowercase letter. All other parameters in the domain are returned unchanged. The _toupper; and _tolower; macros produce the same results as functions toupper and tolower but have restricted domains and are faster. Macro _toupper requires a lowercase letter as its parameter; its result is the corresponding uppercase letter. Macro _tolower requires an uppercase letter as its parameter; its result is the corresponding lowercase letter. Parameters outside the domain cause undefined results. The toascii; macro converts c by clearing all bits that are not part of a standard ASCII character. It is used for compatibility with other systems. Note These routines do not support the Macintosh extended character set (with values greater than 0x7F). For values outside the stated domain, the result is undefined. Warning The _toupper and _tolower macros must be used with care: parameters outside their respective domains cause undefined results. The _toupper macro requires a lowercase letter as its parameter: the _tolower macro requires an uppercase letter as its parameter. See also Character testing æKY isalphaæ æDT int myVariable = isalpha((int) c); æKY isupperæ æDT int myVariable = isupper((int) c); æKY isloweræ æDT int myVariable = islower((int) c); æKY isdigitæ æDT int myVariable = isdigit((int) c); æKY isxdigitæ æDT int myVariable = isxdigit((int) c); æKY isalnumæ æDT int myVariable = isalnum((int) c); æKY isspaceæ æDT int myVariable = isspace((int) c); æKY ispunctæ æDT int myVariable = ispunct((int) c); æKY isprintæ æDT int myVariable = isprint((int) c); æKY isgraphæ æDT int myVariable = isgraph((int) c); æKY iscntrlæ æDT int myVariable = iscntrl((int) c); æKY isasciiæ æDT int my Variable = isascii((int) c); æKY toupperæ æDT int myVariable = toupper((int) c); æKY toloweræ æDT int myVariable = tolower((int) c); æKY _toupperæ æDT int myVariable = _toupper((int) c); æKY _toloweræ æDT int myVariable = _toupper((int) c); æKY toasciiæ æDT int myVariable = toascii((int) c); æKY CursorCtl.h æKL Hide_Cursor InitCursorCtl RotateCursor Show_Cursor SpinCursor acur Acur acurHandle acurPtr ARROW_CURSOR CROSS_CURSOR Cursors HIDDEN_CURSOR I_BEAM_CURSOR PLUS_CURSOR WATCH_CURSOR æKY Acur acur acurPtr acurHandle æFc CursorCtl.h æT struct æD struct Acur { short n; /*Number of cursors ("frames of film")*/ short index; /* Next frame to show <for internal use>*/ short frame1; /*'CURS' resource id for frame #1*/ short fill1; /*<for internal use>*/ short frame2; /*'CURS' resource id for frame #2*/ short fill2; /*<for internal use>*/ short frameN; /*'CURS' resource id for frame #N*/ short fillN; /*<for internal use>*/ }; typedef struct Acur acur,*acurPtr,**acurHandle; æKY Cursors HIDDEN_CURSOR I_BEAM_CURSOR CROSS_CURSOR PLUS_CURSOR WATCH_CURSOR ARROW_CURSOR æFc CursorCtl.h æD enum {HIDDEN_CURSOR,I_BEAM_CURSOR,CROSS_CURSOR,PLUS_CURSOR,WATCH_CURSOR, ARROW_CURSOR}Cursors; typedef unsigned char Cursors; æKY Hide_Cursor æFc CursorCtl.h æT Function æD pascal void Hide_Cursor(void); æDT Hide_Cursor(); æC /* Hide the cursor if it is showing.This is this unit's call to the Mac HideCursor routine.Thus the Mac cursor level is decremented by one when this routine is called. */ æKY InitCursorCtl æFc CursorCtl.h æT Function æD pascal void InitCursorCtl(acurHandle newCursors); æDT InitCursorCtl((acurHandle)newCursors); æC /* Initialize the CursorCtl unit. This should be called once prior to calling RotateCursor or SpinCursor. It need not be called if only Hide_Cursor or Show_Cursor are used. If NewCursors is NULL, InitCursorCtl loads in the 'acur' resource and the 'CURS' resources specified by the 'acur' resource ids. If any of the resources cannot be loaded, the cursor will not be changed. The 'acur' resource is assumed to either be in the currently running tool or application, or the MPW Shell for a tool, or in the System file. The 'acur' resource id must be 0 for a tool or application, 1 for the Shell, and 2 for the System file. If NewCursors is not NULL, it is ASSUMED to be a handle to an 'acur' formatted resource designated by the caller and it will be used instead of doing a GetResource on 'acur'. Note, if RotateCursor or SpinCursor are called without calling InitCursorCtl, then RotateCursor and SpinCursor will do the call for the user the first time it is called. However, the possible disadvantage of using this technique is that the resource memory allocated may have undesirable affect (fragmentation?) on the application. Using InitCursorCtl has the advantage of causing the allocation at a specific time determined by the user. Caution: InitCursorCtl MODIFIES the 'acur' resource in memory. Specifically, it changes each FrameN/fillN integer pair to a handle to the corresponding 'CURS' resource also in memory. Thus if NewCursors is not NULL when InitCursorCtl is called, the caller must guarantee NewCursors always points to a "fresh" copy of an 'acur' resource. This need only be of concern to a caller who wants to repeatly use multiple 'acur' resources during execution of their programs. */ æKY RotateCursor æFc CursorCtl.h æT Function æD pascal void RotateCursor(long counter); æDT RotateCursor((long)counter); æC /* RotateCursor is called to rotate the "I am active" "beach ball" cursor, or to animate whatever sequence of cursors set up by InitCursorCtl. The next cursor ("frame") is used when Counter % 32 = 0 (Counter is some kind of incrementing or decrementing index maintained by the caller). A positive counter sequences forward through the cursors (e.g., it rotates the "beach ball" cursor clockwise), and a negative cursor sequences through the cursors backwards (e.g., it rotates the "beach ball" cursor counterclockwise). Note, RotateCursor just does a Mac SetCursor call for the proper cursor picture. It is assumed the cursor is visible from a prior Show_Cursor call. */ æKY Show_Cursor æFc CursorCtl.h æT Function æD pascal void Show_Cursor(Cursors cursorKind); æDT Show_Cursor((Cursors)cursorKind); æC /* Increment the cursor level, which may have been decremented by Hide_Cursor, and display the specified cursor if the level becomes 0 (it is never incremented beyond 0).The CursorKind is the kind of cursor to show. It is one of the values HIDDEN_CURSOR, I_BEAM_CURSOR, CROSS_CURSOR, PLUS_CURSOR, WATCH_CURSOR, and ARROW_CURSOR. Except for HIDDEN_CURSOR, a Mac SetCursor is done for the specified cursor prior to doing a ShowCursor. HIDDEN_CURSOR just causes a ShowCursor call. Note, ARROW_CURSOR will only work correctly if there is already a grafPort set up pointed to by 0(A5). */ æKY SpinCursor æFc CursorCtl.h æT Function æD pascal void SpinCursor(short increment); æDT SpinCursor((short)increment); æC /* SpinCursor is similar in function to RotateCursor, except that instead of passing a counter, an Increment is passed an added to a counter maintained here. SpinCursor is provided for those users who do not happen to have a convenient counter handy but still want to use the spinning "beach ball" cursor, or any sequence of cursors set up by InitCursorCtl. A positive increment sequences forward through the curos (rotating the "beach ball" cursor clockwise), and a negative increment sequences backward through the cursors (rotating the "beach ball" cursor counter-clockwise). A zero value for the increment resets the counter to zero. Note, it is the increment, and not the value of the counter that determines the sequencing direction of the cursor (and hence the spin direction of the "beach ball" cursor). */ æKY DatabaseAccess.h æKL DBBreak DBDisposeQuery DBEnd DBExec DBGetConnInfo DBGetErr DBGetItem DBGetNewQuery DBGetQueryResults DBGetResultHandler DBGetSessionNum DBInit DBInstallResultHandler DBKill DBRemoveResultHandler DBResultsToText DBSend DBSendItem DBStartQuery DBState DBUnGetItem InitDBPack QuitDBPack DBAsyncParamBlockRec DBAsyncParmBlkPtr DBColInfoRecord DBType kDBAboutToInit kDBExecComplete kDBGetItemComplete kDBGetQueryResultsComplete kDBInitComplete kDBLastColFlag kDBSendComplete kDBStartQueryComplete kDBUpdateWind kDBWaitForever QueryHandle QueryListHandle QueryPtr QueryRecord rcDBAsyncNotSupp rcDBBadAsyncPB rcDBBadDDEV rcDBBadSessID rcDBBadSessNum rcDBBadType rcDBBreak rcDBError rcDBExec rcDBNoHandler rcDBNull rcDBPackNotInited rcDBValue rcDBWrongVersion ResListElem ResListHandle ResultsRecord typeAnyType typeBoolean typeChar typeColBreak typeDate typeDecimal typeDiscard typeFloat typeInteger typeLBin typeLChar typeMoney typeNone typeRowBreak typeSMFloat typeSMInt typeTime typeTimeStamp typeUnknown typeVBin typeVChar æKY rcDBNull æFc DatabaseAccess.h æT #define æD /* OSErr error and status codes */ #define rcDBNull -800 æC æKY rcDBValue æFc DatabaseAccess.h æT #define æD #define rcDBValue -801 æC æKY rcDBError æFc DatabaseAccess.h æT #define æD #define rcDBError -802 æC æKY rcDBBadType æFc DatabaseAccess.h æT #define æD #define rcDBBadType -803 æC æKY rcDBBreak æFc DatabaseAccess.h æT #define æD #define rcDBBreak -804 æC æKY rcDBExec æFc DatabaseAccess.h æT #define æD #define rcDBExec -805 æC æKY rcDBBadSessID æFc DatabaseAccess.h æT #define æD #define rcDBBadSessID -806 æC æKY rcDBBadSessNum æFc DatabaseAccess.h æT #define æD #define rcDBBadSessNum -807 /* bad session number for DBGetConnInfo */ æC æKY rcDBBadDDEV æFc DatabaseAccess.h æT #define æD #define rcDBBadDDEV -808 /* bad ddev specified on DBInit */ æC æKY rcDBAsyncNotSupp æFc DatabaseAccess.h æT #define æD #define rcDBAsyncNotSupp -809 /* ddev does not support async calls */ æC æKY rcDBBadAsyncPB æFc DatabaseAccess.h æT #define æD #define rcDBBadAsyncPB -810 /* tried to kill a bad pb */ æC æKY rcDBNoHandler æFc DatabaseAccess.h æT #define æD #define rcDBNoHandler -811 /* no app handler for specified data type */ æC æKY rcDBWrongVersion æFc DatabaseAccess.h æT #define æD #define rcDBWrongVersion -812 /* incompatible versions */ æC æKY rcDBPackNotInited æFc DatabaseAccess.h æT #define æD #define rcDBPackNotInited -813 /* attempt to call other routine before InitDBPack */ æC æKY kDBUpdateWind æFc DatabaseAccess.h æT #define æD /* messages for status functions for DBStartQuery */ #define kDBUpdateWind 0 æC æKY kDBAboutToInit æFc DatabaseAccess.h æT #define æD #define kDBAboutToInit 1 æC æKY kDBInitComplete æFc DatabaseAccess.h æT #define æD #define kDBInitComplete 2 æC æKY kDBSendComplete æFc DatabaseAccess.h æT #define æD #define kDBSendComplete 3 æC æKY kDBExecComplete æFc DatabaseAccess.h æT #define æD #define kDBExecComplete 4 æC æKY kDBStartQueryComplete æFc DatabaseAccess.h æT #define æD #define kDBStartQueryComplete 5 æC æKY kDBGetItemComplete æFc DatabaseAccess.h æT #define æD /* messages for status functions for DBGetQueryResults */ #define kDBGetItemComplete 6 æC æKY kDBGetQueryResultsComplete æFc DatabaseAccess.h æT #define æD #define kDBGetQueryResultsComplete 7 æC æKY typeNone æFc DatabaseAccess.h æT #define æD /* data type codes */ #define typeNone 'none' æC æKY typeBoolean æFc DatabaseAccess.h æT #define æD #define typeBoolean 'bool' æC æKY typeSMInt æFc DatabaseAccess.h æT #define æD #define typeSMInt 'smin' æC æKY typeInteger æFc DatabaseAccess.h æT #define æD #define typeInteger 'int ' æC æKY typeSMFloat æFc DatabaseAccess.h æT #define æD #define typeSMFloat 'smfl' æC æKY typeFloat æFc DatabaseAccess.h æT #define æD #define typeFloat 'flot' æC æKY typeDate æFc DatabaseAccess.h æT #define æD #define typeDate 'date' æC æKY typeTime æFc DatabaseAccess.h æT #define æD #define typeTime 'time' æC æKY typeTimeStamp æFc DatabaseAccess.h æT #define æD #define typeTimeStamp 'tims' æC æKY typeChar æFc DatabaseAccess.h æT #define æD #define typeChar 'char' æC æKY typeDecimal æFc DatabaseAccess.h æT #define æD #define typeDecimal 'decm' æC æKY typeMoney æFc DatabaseAccess.h æT #define æD #define typeMoney 'mony' æC æKY typeVChar æFc DatabaseAccess.h æT #define æD #define typeVChar 'vchr' æC æKY typeVBin æFc DatabaseAccess.h æT #define æD #define typeVBin 'vbin' æC æKY typeLChar æFc DatabaseAccess.h æT #define æD #define typeLChar 'lchr' æC æKY typeLBin æFc DatabaseAccess.h æT #define æD #define typeLBin 'lbin' æC æKY typeDiscard æFc DatabaseAccess.h æT #define æD #define typeDiscard 'disc' æC æKY typeUnknown æFc DatabaseAccess.h æT #define æD /* "dummy" types for DBResultsToText */ #define typeUnknown 'unkn' æC æKY typeColBreak æFc DatabaseAccess.h æT #define æD #define typeColBreak 'cbrk' æC æKY typeRowBreak æFc DatabaseAccess.h æT #define æD #define typeRowBreak 'rbrk' æC æKY typeAnyType æFc DatabaseAccess.h æT #define æD /* pass this in to DBGetItem for any data type */ #define typeAnyType (DBType)0 æC æKY kDBWaitForever æFc DatabaseAccess.h æT #define æD /* infinite timeout value for DBGetItem */ #define kDBWaitForever -1 æC æKY kDBLastColFlag æFc DatabaseAccess.h æT #define æD /* flag for last column in row for DBGetItem */ #define kDBLastColFlag 0x0001 æC æKY DBType æFc DatabaseAccess.h æT typedef æD typedef OSType DBType; æC æKY QueryListHandle æFc DatabaseAccess.h æT typedef æD typedef Handle **QueryListHandle; /* just handles to 'wstr' resources */ æC æKY DBAsyncParamBlockRec DBAsyncParmBlkPtr æFc DatabaseAccess.h æT struct æD struct DBAsyncParamBlockRec { ProcPtr completionProc; /* pointer to completion routine */ OSErr result; /* result of call */ long userRef; /* for application's use */ long ddevRef; /* for ddev's use */ long reserved; /* for internal use */ }; typedef struct DBAsyncParamBlockRec DBAsyncParamBlockRec; typedef DBAsyncParamBlockRec *DBAsyncParmBlkPtr; /* structure for resource list in QueryRecord */ æC æKY ResListElem ResListHandle æFc DatabaseAccess.h æT struct æD struct ResListElem { ResType theType; /* resource type */ short id; /* resource id */ }; typedef struct ResListElem ResListElem; /* structure for query list in QueryRecord */ æC æKY QueryRecord QueryPtr QueryHandle æFc DatabaseAccess.h æT struct æD struct QueryRecord { Short version; /* version */ Short id; /* id of 'qrsc' this came from */ Handle queryProc; /* handle to query def proc */ Str63 ddevName; /* ddev name */ Str255 host; /* host */ Str255 user; /* user */ Str255 password; /* password */ Str255 connStr; /* connection string */ Short currQuery; /* current query */ Short numQueries; /* number of queries in queryList */ QueryListHandle queryList; /* handle to list of queries */ Short numRes; /* number of resources in resList */ ResListHandle resList; /* handle to list of other resources */ Handle dataHandle; /* data used by query def proc */ long refCon; /* query's reference value */ }; typedef struct QueryRecord QueryRecord; typedef QueryRecord *QueryPtr, **QueryHandle; /* structure of column types array in ResultsRecord */ æC æKY DBColInfoRecord æFc DatabaseAccess.h æT struct æD struct DBColInfoRecord { short len; short places; short flags; }; typedef struct DBColInfoRecord DBColInfoRecord; æC æKY ResultsRecord æFc DatabaseAccess.h æT struct æD struct ResultsRecord { Short numRows; /* number of rows in result */ Short numCols; /* number of colums per row */ Handle colTypes; /* data type array*/ Handle colData; /* actual results */ Handle colInfo; /* DBColInfoRecord array */ }; typedef struct ResultsRecord ResultsRecord; æC æKY InitDBPack æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr InitDBPack(void) = {0x3F3C,0x0004,0x303C,0x0100,0xA82F}; æDT OSErr myVariable = InitDBPack()(void); æC You must call the InitDBPack function before you call any other Database Access Manager routines. You must call the QuitDBPack function when you are finished using the Database Access Manager. The InitDBPack function causes the Package Manager to load the Database Access Manager into memory, if it has not already done so, and increments the Database Access Manager use counter. The use counter prevents any application from removing the Database Access Manager from memory while another application is using it. The interface routine that implements the InitDBPack function includes a version number for the Database Access Manager. If the package is a different version than specified by the interface routine, then the InitDBPack function returns the rcDBWrongVersion result code. Result codes noErr 0 No error rcDBWrongVersion –814 Wrong version number æKY QuitDBPack æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr QuitDBPack(void) = {0x303C,0x0001,0xA82F}; æDT OSErr myVariable = QuitDBPack()(void); æC The QuitDBPack function decrements the Database Access Manager use counter. When this counter equals 0, the QuitDBPack function removes the Database Access Manager package from memory. Call this routine when your application is terminating or when you are finished using the Database Access Manager. The use counter prevents the QuitDBPack function from removing the Database Access Manager from memory while any application is still using it. Result codes noErr 0 No error rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBInit æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBInit(long *sessID,const Str63 ddevName,const Str255 host, const Str255 user,const Str255 passwd,const Str255 connStr,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0E02,0xA82F}; æDT OSErr myVariable = DBInit((long *) sessID,(const Str63) ddevName,(const Str255) host,( const) Str255 user,(const Str255) passwd,(const Str255) connStr,(DBAsyncParmBlkPtr) asyncPB); æC The DBInit function initiates a session with a remote database server. You must initiate a session before you call any Database Access Manager function that requires a session ID as an input parameter. If the DBInit function returns a nonzero session ID, you must call the DBEnd function to terminate the session, even if the DBInit function also returns a result code other than noErr. Because the high-level function DBStartQuery can call the DBInit function, if you have called the DBStartQuery function, you do not have to call the DBInit function. The DBInit function returns the session ID in the sessID parameter. This session ID is unique; no other current session, for any database extension, has the same session ID. You must specify the session ID any time you want to send data to or retrieve data from this session. Depending on the database extension you are using, the DBInit function might return a session ID of 0 if it fails to initiate a session, or it might return a nonzero session ID and a result code other than noErr. In the latter case, you can pass the session ID to the DBGetErr function to determine the cause of the error. The ddevName parameter is a string of no more than 63 characters that specifies the name of the database extension. The name of the database extension is contained in the database extension file in a resource of type 'STR ' with an ID of 128. For the CL/1 database extension provided by Apple , for example, this string is “CL/1”. The host parameter specifies the name of the remote system on which the database server is located. This name depends on the manner in which the database extension establishes communication with the remote database server and on how the system administrator has set up the computer system. The user parameter specifies the name of the user, and the password parameter specifies the password associated with the user name. The connStr parameter is a connection string that is passed to the database server, which might pass it on to the database management software on the remote computer. This string is necessary in some systems to complete log-on procedures. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBError –802 Error initiating session rcDBBadDDev –809 Couldn’t find specified database extension or trouble opening ddev file rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBEnd æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBEnd(long sessID,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0403,0xA82F}; æDT OSErr myVariable = DBEnd((long) sessID,(DBAsyncParmBlkPtr) asyncPB); æC The DBEnd function terminates a session with a remote database server and terminates the network connection between the application and the remote computer. You must call the DBEnd function to terminate a session. The sessID parameter is the session ID that was returned by the DBInit function. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBError –802 Error ending session rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBGetConnInfo æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBGetConnInfo(long sessID,Short sessNum,long *returnID,long *version, const Str63 ddevName,const Str255 host,const Str255 user,const Str255 network, const Str255 connStr,long *start,OSErr *state,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x1704,0xA82F}; æDT OSErr myVariable = DBGetConnInfo((long) sessID,(Short) sessNum,(long *) returnID,(long *) version,( const) Str63 ddevName,(const Str255) host,(const Str255) user,(const Str255) network,( const) Str255 connStr,(long *) start,(OSErr *) state,(DBAsyncParmBlkPtr) asyncPB); æC The DBGetConnInfo function returns information about the specified session, including • the version of the database extension • the name of the remote system on which the session is running • the user name • the connection string that was used to establish communication • the name of the network • the time at which the session started, in ticks • the status of the session In addition, if you include a nonzero value for the sessID parameter when you call the DBGetConnInfo function, the function returns the name of the database extension. If you use 0 for the sessID parameter and specify the database extension and session number instead, the function returns the session ID. You can use this function to get information about a particular session, or you can call the function repeatedly, incrementing the session number each time, to get information about all of the sessions associated with a particular database extension. The sessID parameter is the session ID that was returned by the DBInit function. The sessNum parameter is the session number of the session about which you want information. You can specify either the session ID or the session number when you call the DBInit function. If you specify the sessID parameter, use 0 for the sessNum parameter. If you specify the sessNum parameter, then use 0 for the sessID parameter. If you specify the sessNum parameter, you must specify a value for the ddevName parameter as well. If you specify the session number and the database extension, then the DBGetConnInfo function returns the session ID in the returnedID parameter. The version parameter returns the version number of the database extension that is the interface to the remote database server on which this session is running. The ddevName parameter specifies the name of the database extension. If you specify 0 for the session ID, you must include the name of the database extension as well as a session number. If you specify a valid session ID, then the DBGetConnInfo function returns the name of the database extension in the ddevName parameter. The name of the database extension is included in a 'STR ' resource in the database extension file with a resource ID of 128. The host, user, and connStr parameters are the host, user, and connection strings that were used to establish communication with the remote database server. The network parameter is the name of the network through which your computer is communicating with the remote database server. The start parameter is the time, in ticks, at which this session was initiated. The state parameter returns one of the following values to provide information about the status of the session: CONST noErr = 0 ;No error; ready for more text rcDBValue = –801 ;Output data available rcDBError = –802 ;Execution ended in an error rcDBExec = –806 ;Busy; currently executing query The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBBadSessNum –808 Invalid session number rcDBBadSessID –807 Session ID is invalid or database extension name is invalid rcDBBadDDev –809 Couldn’t find specified database extension or trouble opening ddev file rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBGetSessionNum æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBGetSessionNum(long sessID,Short *sessNum,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0605,0xA82F}; æDT OSErr myVariable = DBGetSessionNum((long) sessID,(Short *) sessNum,(DBAsyncParmBlkPtr) asyncPB); æC The DBGetSessionNum function returns the session number of the session you specify with the session ID parameter. The session number is unique for a particular database extension, but the same session number might be in use for different database extensions at the same time. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBSend æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBSend(long sessID,char *text,Short len,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0706,0xA82F}; æDT OSErr myVariable = DBSend((long) sessID,(char *) text,(Short) len,(DBAsyncParmBlkPtr) asyncPB); æC The DBSend function sends a query or a portion of a query to the remote database server. The database server appends this portion of the query to any portion you sent previously. Because the Database Access Manager and database server do not modify the string you send in any way, they do not insert any delimiter between fragments of queries that you send to the database server. If you want a blank or a semicolon to be included between query fragments, or if you want to use return characters to divide the query into lines of text, you must include them in the character string that you send with this function. The database server does not execute the query until you call the DBExec function. The sessID parameter is the session ID that was returned by the DBInit function. The text parameter is a pointer to the query or query fragment that you want to send to the database server. The query or query fragment must be a character string. The len parameter specifies the length of the character string. If the len parameter has a value of –1, then the character string is assumed to be “NULL terminated” (that is, the string ends with a NULL byte); otherwise, the len parameter specifies the number of bytes in the string. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBError –802 Error trying to send text rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBSendItem æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBSendItem(long sessID,char dataType,Short len,Short places, Short flags,Ptr buffer,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0B07,0xA82F}; æDT OSErr myVariable = DBSendItem((long) sessID,(char) dataType,(Short) len,(Short) places,() Short flags,(Ptr) buffer,(DBAsyncParmBlkPtr) asyncPB); æC The DBSendItem function sends a single data item to the remote database server. You can use this function to send to the database server the data that you wish to include in a query. The database extension or the database server (depending on how the system is implemented) converts the data item to a character string and appends it to the query, just as a query program fragment is appended to the query by the DBSend function. The query is not executed until you call the DBExec function. The sessID parameter is the session ID that was returned by the DBInit function. The dataType, len, and places parameters specify the data type, length, and number of decimal places for the data item that you are sending to the remote database server. The database extension and database server ignore the len parameter if the data type has an implied length. The database extension and database server ignore the places parameter for all values of the dataType parameter except typeDecimal and typeMoney. Data types are discussed in “Getting Query Results” earlier in this chapter. The buffer parameter is a pointer to the memory location of the data item that you want to send. When you use the DBSendItem function to send an item of data to a database server, the database extension and database server format the data according to the data type, length, and decimal places you specified, converts it to a character string, and appends the data to the query. Set the flags parameter to 0. There are no flags currently defined for the DBSendItem function. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBError –802 Error trying to send item rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBExec æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBExec(long sessID,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0408,0xA82F}; æDT OSErr myVariable = DBExec((long) sessID,(DBAsyncParmBlkPtr) asyncPB); æC The DBExec function initiates execution of a query that you have sent to the remote database server. Use the DBSend and DBSendItem functions to send a query to the database server. Use the DBState function to determine the status of a query after you have initiated execution. The sessID parameter is the session ID that was returned by the DBInit function. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 Execution has begun rcDBError –802 Error trying to begin execution rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBState æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBState(long sessID,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0409,0xA82F}; æDT OSErr myVariable = DBState((long) sessID,(DBAsyncParmBlkPtr) asyncPB); æC The result code returned by the DBState function indicates the status of the remote database server. You can use this function to determine whether the database server has successfully executed a query and whether it has data available for you to retrieve. The sessID parameter is the session ID that was returned by the DBInit function. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error; ready for more text rcDBValue –801 Output data available rcDBError –802 Execution ended in an error rcDBExec –806 Currently executing query rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBGetErr æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBGetErr(long sessID,long *err1,long *err2,const Str255 item1, const Str255 item2,const Str255 errorMsg,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0E0A,0xA82F}; æDT OSErr myVariable = DBGetErr((long) sessID,(long *) err1,(long *) err2,(const Str255) item1,( const) Str255 item2,(const Str255) errorMsg,(DBAsyncParmBlkPtr) asyncPB); æC The DBGetErr function retrieves error codes and error messages from a remote database server. You can use this function to obtain information when a low-level function returns the result code rcDBError. If the DBState function returns the rcDBError result code, indicating that execution of a query ended in an error, the error information can help you debug the query. The meaning of each error code and error message returned by this function depends on the database server with which you are communicating; see the documentation for that database server for more information. The sessID parameter is the session ID that was returned by the DBInit function. The err1 and err2 parameters return the primary and secondary error codes. The item1 and item2 parameters return strings that describe the objects of the error message. The errorMsg parameter returns the error message. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBError –802 Error retrieving error information rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBBreak æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBBreak(long sessID,Boolean abort,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x050B,0xA82F}; æDT OSErr myVariable = DBBreak((long) sessID,(Boolean) abort,(DBAsyncParmBlkPtr) asyncPB); æC The DBBreak function can halt execution of a query and reinitialize the remote database server, or it can unconditionally terminate a session with a database server. You can use this function to cancel a query if you determine that it is taking too long to complete execution, for example. The sessID parameter is the session ID that was returned by the DBInit function. If the abort parameter is TRUE (nonzero), the database server halts any query that is executing and terminates the current session. If the abort parameter is FALSE (0), the database server halts any query that is executing and reinitializes itself. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 Execution has begun rcDBError –802 Break or abort attempt was unsuccessful rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBGetItem æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBGetItem(long sessID,long timeout,char *dataType,sort *len, Short *places,Short *flags,Ptr buffer,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x100C,0xA82F}; æDT OSErr myVariable = DBGetItem((long) sessID,(long) timeout,(char *) dataType,(sort *) len,( Short) * places,(Short *) flags,(Ptr) buffer,(DBAsyncParmBlkPtr) asyncPB); æC The DBGetItem function retrieves the next data item from the database server. You can also use this function to obtain information about the next data item without retrieving the data. You can use the DBGetItem function after you have executed a query and the DBState function has returned the result code rcDBValue, indicating that data is available. You can repeat the DBGetItem function as many times as is necessary to retrieve all of the data returned by the database in response to a query. The sessID parameter is the session ID that was returned by the DBInit function. You can use the timeout parameter to specify the maximum amount of time that the database extension should wait to receive results from the database server before canceling the function. Specify the timeout parameter in sixtieths of a second. To disable the timeout feature, set the timeout parameter to the value kDBWaitForever. If the timeout period expires, the DBGetItem function returns the result code rcDBBreak. The DBGetItem function ignores the timeout parameter if you call the function asynchronously. One use for the timeout parameter is to call the DBGetItem function periodically with a short value set for this parameter in order to return control to your application while a query is executing. Your application can then retrieve the next data item as soon as execution of the query is complete without having to call the DBState function to determine when data is available. You can set the dataType parameter to specify the data type that you expect the next data item to be. If the item is not of the expected data type, the database extension returns the rcDBBadType result code. If you want to retrieve the next data item regardless of type, set the dataType parameter to the value typeAnyType. To skip the next data item, set the dataType parameter to the value typeDiscard. The database server sets the dataType parameter to the actual type of the data item when it retrieves the data item or returns information about the data item. Data types are discussed in “Getting Query Results” earlier in this chapter. Set the len parameter to the length of the data buffer pointed to by the buffer parameter. If you use the DBGetItem function to obtain information only (by setting the buffer parameter to NIL), then the database server ignores the len parameter. The database server sets the len parameter to the actual length of the data item when it retrieves the data item or returns information about the data item. The database server returns in the places parameter the number of decimal places in data items of types typeMoney and typeDecimal. For all other data types, the database server returns 0 for the places parameter. The buffer parameter is a pointer to the location where you want the retrieved data item to be stored. You must ensure that the location you specify contains enough space for the data item that will be returned. To determine the data type, length, and number of decimal places of the next data item without retrieving it, specify NIL for the buffer parameter. If the flags parameter is set to kDBLastColFlag (that is, the least significant bit is set to 1), the data item is in the last column of the row. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error; no next data item rcDBNull –800 The data item was NULL rcDBValue –801 A nonzero data item was successfully retrieved rcDBError –802 Execution ended in an error rcDBBadType –803 Next data item not of requested data type rcDBBreak –805 Timed out rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBUnGetItem æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBUnGetItem(long sessID,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x040D,0xA82F}; æDT OSErr myVariable = DBUnGetItem((long) sessID,(DBAsyncParmBlkPtr) asyncPB); æC The DBUnGetItem function reverses the effect of the last call to the DBGetItem function, in the sense that the next time you call the DBGetItem function it retrieves the same item a second time. It does not remove the just-retrieved data item from the input buffer. The DBUnGetItem function can reverse the effect of only one call to the DBGetItem function; you cannot use it to step back through several previously retrieved data items. The sessID parameter is the session ID that was returned by the DBInit function. The asyncPB parameter is a pointer to the asynchronous parameter block. If you do not want to call the function asynchronously, set this parameter to NIL. Result codes noErr 0 No error rcDBError –802 Error executing function rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 Asynchronous calls are not supported by database extension rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBKill æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBKill(DBAsyncParmBlkPtr asyncPB) = {0x303C,0x020E,0xA82F}; æDT OSErr myVariable = DBKill((DBAsyncParmBlkPtr) asyncPB); æC The DBKill function cancels the execution of the asynchronous call specified by the asyncPB parameter. The asyncPB parameter is a pointer to the asynchronous parameter block. Result codes noErr 0 Asynchronous routine canceled successfully rcDBError –802 Error canceling routine rcDBBadAsynchPB –812 Invalid parameter block specified rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBGetNewQuery æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBGetNewQuery(Short queryID,QueryHandle *qeury) = {0x303C,0x030F,0xA82F}; æDT OSErr myVariable = DBGetNewQuery((Short) queryID,(QueryHandle *) qeury); æC The DBGetNewQuery function creates a query record from the 'qrsc' resource with the resource ID you specify in the queryID parameter. The resource file that contains the 'qrsc' resource must remain open until after the DBStartQuery function has completed execution. If you do not already know the resource ID of the 'qrsc' resource (for example, if you call the SFGetFile procedure to let the user select the query document), you can use Resource Manager routines to determine the resource ID. The SFGetFile procedure is described in the Standard File Package chapter of Volume I and the Resource Manager is described in Volume Chapter 5. The queryID parameter specifies the resource ID of the 'qrsc' resource that you want to use. The query parameter returns a handle to the query record. Result code noErr 0 Query record built successfully rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBDisposeQuery æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBDisposeQuery(QueryHandle query) = {0x303C,0x0210,0xA82F}; æDT OSErr myVariable = DBDisposeQuery((QueryHandle) query); æC The DBDisposeQuery function disposes of a query record and frees all the memory that the Database Access Manager allocated when it created the query record. You should call this function after you are finished using a query record. The query parameter is a handle to the query record. Result code noErr 0 Query record disposed of successfully rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBStartQuery æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBStartQuery(long *sessID,QueryHandle query,ProcPtr statusProc, DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0811,0xA82F}; æDT OSErr myVariable = DBStartQuery((long *) sessID,(QueryHandle) query,(ProcPtr) statusProc,() DBAsyncParmBlkPtr asyncPB); æC The DBStartQuery function performs the following tasks, in the order specified: 1. It calls the query definition function (if any) pointed to by the query record. The query definition function modifies the query record and the query, usually by asking the user for input. The query definition function can display a dialog box that gives the user the option of canceling the query; if the user does cancel the query, the DBStartQuery function returns the userCanceledErr result code. 2. If you specify a nonzero value for the statusProc parameter, the DBStartQuery function calls your status routine with the value kDBUpdateWind in the message parameter so that your application can update its windows. 3. If you specify a nonzero value for the statusProc parameter, the DBStartQuery function calls your status routine with the value kDBAboutToInit in the message parameter so that your application can display a dialog box informing the user that a database session is about to be established, and giving the user the option of canceling execution of the function. 4. If the sessID parameter is 0, the DBStartQuery function calls the DBInit function to establish a database session, and returns a session ID. 5. If you specify a nonzero value for the statusProc parameter and the DBStartQuery function called the DBInit function, the DBStartQuery function calls your status routine with the value kDBInitComplete in the message parameter and the result of the DBInit function in the result parameter. 6. The DBStartQuery function calls the DBSend function to send the query to the remote database server. 7. If you specify a nonzero value for the statusProc parameter, the DBStartQuery function calls your status routine with the value kDBSendComplete in the message parameter and the result of the DBSend function in the result parameter. 8. The DBStartQuery function calls the DBExec function to execute the query. 9. If you specify a nonzero value for the statusProc parameter, the DBStartQuery function calls your status routine with the value kDBExecComplete in the message parameter and the result of the DBExec function in the result parameter. 10. If you specify a nonzero value for the statusProc parameter, the DBStartQuery function calls your status routine with the value kDBStartQueryComplete in the message parameter and the result of the DBStartQuery function in the result parameter. You can use the sessID parameter to specify a session ID if your application or another application has already established a session with the database server. If you specify NIL for this parameter, then the DBStartQuery function establishes a session and returns the session ID in the sessID parameter. You use the query parameter to specify a handle to a query record. You can use the statusProc pointer to specify a pointer to a status routine that your application can use to update its windows after the query definition function has completed execution. If you specify NIL for this parameter, the DBStartQuery function does not attempt to update your application’s windows. The DBStartQuery function also calls your status routine before it initiates a database session, after it calls the DBInit function, after it calls the DBSend function, and after it calls the DBExec function. Status routines are discussed in “Writing a Status Routine for High-Level Functions” earlier in this chapter. If you specify a pointer to an asynchronous parameter block in the asyncPB parameter, the DBStartQuery function calls the DBInit, DBSend, and DBExec functions asynchronously. As soon as the DBInit function has started execution, it returns control to your application. Your application must then call the WaitNextEvent routine periodically to allow these asynchronous routines to run, and it must check the result field of the asynchronous parameter block to determine when each routine has completed execution. Result codes noErr 0 No error userCanceledErr –128 User canceled the query rcDBError –802 Error initiating session, sending text, or executing query rcDBBadDDev –809 Couldn’t find the specified database extension, or error occurred in opening database extension rcDBAsyncNotSupp –811 The database extension does not support asynchronous calls rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBGetQueryResults æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBGetQueryResults(long sessID,ResultsRecord *results,long timeout, ProcPtr statusProc,DBAsyncParmBlkPtr asyncPB) = {0x303C,0x0A12,0xA82F}; æDT OSErr myVariable = DBGetQueryResults((long) sessID,(ResultsRecord *) results,(long) timeout,() ProcPtr statusProc,(DBAsyncParmBlkPtr) asyncPB); æC The DBGetQueryResults function retrieves the results returned by a query and places them in memory. If there is sufficient memory available, this function retrieves all of the results at once. If the DBGetQueryResults function runs out of memory, it places as much data as possible in memory, up to the last whole row. You can then make more memory available and call the DBGetQueryResults function again to retrieve more data. The DBGetQueryResults function can be used to retrieve the results of any query, not only queries sent and executed by the DBStartQuery function. The sessID parameter specifies the ID of the session from which you wish to retrieve results. The results parameter is the results record, which contains a handle to the retrieved data. Results records are described in “Getting Query Results” earlier in this chapter. The timeout parameter specifies the value that he DBGetQueryResults uses for the timeout parameter each time it calls the DBGetItem function. The timeout parameter specifies the maximum amount of time that the database extension should wait to receive results from the database server before canceling the DBGetItem function. Specify the timeout parameter in sixtieths of a second. To disable the timeout feature, set the timeout parameter to the value kDBWaitForever. This parameter is ignored if you specify a nonzero value for the asyncPB parameter. You can use the statusProc pointer to specify a pointer to a status routine that you provide. The DBGetQueryResults function calls your status routine after it calls the DBGetItem function to retrieve a data item. When it calls the status routine, the DBGetQueryResults function provides the results of the DBGetItem function, the data type, the data length, number of decimal places, and flags associated with the data item, and a pointer to the data item. Status routines are discussed in “Writing a Status Routine For High-Level Functions” earlier in this chapter. If you specify a pointer to an asynchronous parameter block in the asyncPB parameter, the DBGetQueryResults function calls the DBGetItem function asynchronously for each data item. As soon as the DBGetItem function has started execution, it returns control to your application. Your application must then call the WaitNextEvent routine periodically to allow this asynchronous routine to run, and it must check the result field of the asynchronous parameter block to determine when the routine has completed execution. Result codes noErr 0 Query execution successful; no results returned userCanceledErr –128 Function canceled by status routine rcDBValue –801 Data available rcDBError –802 Query execution ended in an error rcDBBreak –805 Function timed out rcDBExec –806 Query currently executing rcDBBadSessID –807 Session ID is invalid rcDBAsyncNotSupp –811 The database extension does not support asynchronous calls rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBResultsToText æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBResultsToText(ResultsRecord *results,Handle *theText) = {0x303C,0x0413,0xA82F}; æDT OSErr myVariable = DBResultsToText((ResultsRecord *) results,(Handle *) theText); æC The DBResultsToText function calls result handlers to convert to text the data retrieved by the DBGetQueryResults function. Result handlers are described in “Converting Query Results to Text” earlier in this chapter. The results parameter is the results record returned by the DBGetQueryResults function. The parameter theText contains a handle to the converted text. This handle is allocated by the Database Access Manager. Result code noErr 0 No error rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBInstallResultHandler æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBInstallResultHandler(char dataType,ProcPtr theHandler,Boolean isSysHandler) = {0x303C,0x0514,0xA82F}; æDT OSErr myVariable = DBInstallResultHandler((char) dataType,(ProcPtr) theHandler,(Boolean) isSysHandler); æC The DBInstallResultHandler function installs a result handler for the data type specified by the dataType parameter. The result handler is then used by the DBResultsToText function to convert data of the specified type into a character string. The parameter theHandler is a pointer to the result handler. The isSysHandler parameter specifies whether the result handler is an application result handler—to be used only when the DBResultsToText function is called by the application that installed the result handler—or a system result handler—to be used by every application running on the system. When you install an application result handler, it replaces any result handler with the same name previously installed by that application. Similarly, when you install a system result handler, it replaces any existing system result handler with the same name. Before you temporarily replace an existing result handler, use the DBGetResultHandler function to obtain a pointer to the present handler, and save the present result handler in your application’s private storage. Then you can reinstall the original result handler when you are finished using the temporary one. Because an application result handler is used in preference to a system result handler if both are available, you can temporarily replace a system result handler for purposes of your application by installing an application result handler for the same data type. You can then use the DBRemoveResultHandler function to remove the application result handler and return to using the system result handler whenever you wish. Result code noErr 0 No error rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBRemoveResultHandler æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBRemoveResultHandler(char dataType) = {0x303C,0x0215,0xA82F}; æDT OSErr myVariable = DBRemoveResultHandler((char) dataType); æC The DBRemoveResultHandler function removes from memory the application result handler for the data type that you specify with the dataType parameter. This function cannot remove a system result handler. Result codes noErr 0 No error rcDBNoHandler –813 There is no handler for this data type installed for the current application rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DBGetResultHandler æFc DatabaseAccess.h æT Function æTN A82F æD pascal OSErr DBGetResultHandler(char dataType,ProcPtr *theHandler,Boolean getSysHandler) = {0x303C,0x0516,0xA82F}; æDT OSErr myVariable = DBGetResultHandler((char) dataType,(ProcPtr *) theHandler,(Boolean) getSysHandler); æC The DBGetResultHandler function returns a pointer to a result handler for the data type specified with the dataType parameter. The pointer is returned in the parameter theHandler. If you set the isSysHandler parameter to FALSE (0), the function returns a pointer to the current application result handler for the specified data type, or it returns 0 if there is no application result handler for that data type. If you set the isSysHandler parameter to TRUE (nonzero), the function returns a pointer to the current system result handler for the specified data type, or it returns 0 if there is no system result handler for that data type. You can use this function to obtain a pointer to a result handler so that you can use it to convert to text an individual data item retrieved by the DBGetItem function. The DBGetQueryResults function automatically converts to text all of the data pointed to by the results record. Result codes noErr 0 No error rcDBNoHandler –813 There is no handler for this data type installed rcDBPackNotInited –815 The InitDBPack function has not yet been called æKY DDEV.h æKL DDEVFlags DDEVParams DDEVParamsPtr kAsyncSupported kDBBreak kDBClose kDBEnd kDBExec kDBGetConnInfo kDBGetErr kDBGetItem kDBGetSessionNum kDBIdle kDBInit kDBKill kDBOpen kDBSend kDBSendItem kDBState kDBUnGetItem kDDEVFlags kDDEVID kDDEVName æKY kDBInit æFc DDEV.h æT #define æD /* messages for ddev */ #define kDBInit 0 æC æKY kDBEnd æFc DDEV.h æT #define æD #define kDBEnd 1 æC æKY kDBGetConnInfo æFc DDEV.h æT #define æD #define kDBGetConnInfo 2 æC æKY kDBGetSessionNum æFc DDEV.h æT #define æD #define kDBGetSessionNum 3 æC æKY kDBSend æFc DDEV.h æT #define æD #define kDBSend 4 æC æKY kDBSendItem æFc DDEV.h æT #define æD #define kDBSendItem 5 æC æKY kDBExec æFc DDEV.h æT #define æD #define kDBExec 6 æC æKY kDBState æFc DDEV.h æT #define æD #define kDBState 7 æC æKY kDBGetErr æFc DDEV.h æT #define æD #define kDBGetErr 8 æC æKY kDBBreak æFc DDEV.h æT #define æD #define kDBBreak 9 æC æKY kDBGetItem æFc DDEV.h æT #define æD #define kDBGetItem 10 æC æKY kDBUnGetItem æFc DDEV.h æT #define æD #define kDBUnGetItem 11 æC æKY kDBKill æFc DDEV.h æT #define æD #define kDBKill 12 æC æKY kDBOpen æFc DDEV.h æT #define æD #define kDBOpen 100 æC æKY kDBClose æFc DDEV.h æT #define æD #define kDBClose 101 æC æKY kDBIdle æFc DDEV.h æT #define æD #define kDBIdle 102 æC æKY kDDEVName æFc DDEV.h æT #define æD /* resource IDs of misc. resources */ #define kDDEVName 128 /* ID of 'STR ' resource with ddev name */ æC æKY kDDEVID æFc DDEV.h æT #define æD #define kDDEVID 128 /* ID of 'ddev' resource */ æC æKY kDDEVFlags æFc DDEV.h æT #define æD #define kDDEVFlags 128 /* ID of 'dflg' resource */ æC æKY kAsyncSupported æFc DDEV.h æT #define æD #define kAsyncSupported 0x00000001 /* bit for async support */ æC æKY DDEVFlags æFc DDEV.h æT struct æD struct DDEVFlags { long version; /* always 0 for this release */ long flags; /* flags */ }; typedef struct DDEVFlags DDEVFlags; æC æKY DDEVParams DDEVParamsPtr æFc DDEV.h æT struct æD struct DDEVParams { Short message; /* action for ddev */ long ddevStorage; /* storage for ddev */ DBAsyncParmBlkPtr asyncPB; /* async parameter block pointer */ long sessID; /* session ID */ long returnedID; /* session ID returned by DBGetConnInfo */ long version; /* version returned by DBGetConnInfo */ long start; /* start returned by DBGetConnInfo */ StringPtr host; /* host for DBInit and DBGetConnInfo */ StringPtr user; /* user for DBInit and DBGetConnInfo */ StringPtr password; /* password for DBInit and DBGetConnInfo */ StringPtr connStr; /* connection string for DBInit and DBGetConnInfo */ StringPtr network; /* network for DBInit and DBGetConnInfo */ Ptr buffer; /* buffer used in several calls */ long err1; /* error 1 for DGGetErr */ long err2; /* error 2 for DGGetErr */ StringPtr item1; /* item 1 for DGGetErr */ StringPtr item2; /* item 2 for DGGetErr */ StringPtr errorMsg; /* errorMsg for DGGetErr */ long timeout; /* timeout for DGGetItem*/ DBType dataType; /* type for several calls */ Short sessNum; /* session number for DBGetConnInfo and DBGetSessionNum*/ Short state; /* state for DBGetConnInfo */ Short len; /* length of buffer */ Short places; /* places for DBSendItem and DBGetItem */ Short flags; /* flags for DBSendItem and DBGetItem */ Boolean abort; /* abort for DBBreak */ }; typedef struct DDEVParams DDEVParams; typedef DDEVParams *DDEVParamsPtr; æC æKY Desk.h æKL CloseDeskAcc opendeskacc OpenDeskAcc SystemClick SystemEdit SystemEvent SystemMenu SystemTask accClear accCopy accCursor accCut accEvent accMenu accPaste accRun accUndo goodbye æKY accEvent æFc Desk.h æT #define æD #define accEvent 64 æC æKY accRun æFc Desk.h æT #define æD #define accRun 65 æC æKY accCursor æFc Desk.h æT #define æD #define accCursor 66 æC æKY accMenu æFc Desk.h æT #define æD #define accMenu 67 æC æKY accUndo æFc Desk.h æT #define æD #define accUndo 68 æC æKY accCut æFc Desk.h æT #define æD #define accCut 70 æC æKY accCopy æFc Desk.h æT #define æD #define accCopy 71 æC æKY accPaste æFc Desk.h æT #define æD #define accPaste 72 æC æKY accClear æFc Desk.h æT #define æD #define accClear 73 æC æKY goodbye æFc Desk.h æT #define æD #define goodbye -1 /*goodbye message*/ æC æKY OpenDeskAcc æFc Desk.h æT Function æTN A9B6 æD pascal short OpenDeskAcc(const Str255 theAcc) = 0xA9B6; æDT short myVariable = OpenDeskAcc((const Str255) theAcc); æMM æRI I-440 æC OpenDeskAcc opens the desk accessory having the given name and displays its window (if any) as the active window. The name is the accessory’s resource name, which you get from the Apple menu by calling the Menu Manager procedure GetItem. OpenDeskAcc calls the Resource Manager to read the desk accessory from the resource file into the application heap. You should ignore the value returned by OpenDeskAcc. If the desk accessory is successfully opened, the function result is its driver reference number. However, if the desk accessory can’t be opened, the function result is undefined; the accessory will have taken care of informing the user of the problem (such as memory full) and won’t display itself. Warning: Early versions of some desk accessories may set the current grafPort to the accessory’s port upon return from OpenDeskAcc. To be safe, you should bracket your call to OpenDeskAcc with calls to the QuickDraw procedures GetPort and SetPort, to save and restore the current port. Note: Programmers concerned about the amount of available memory should be aware that an open desk accessory uses from 1K to 3K bytes of heap space in addition to the space needed for the accessory itself. The desk accessory is responsible for determining whether there is sufficient memory for it to run; this can be done by calling SizeResource followed by ResrvMem. æKY CloseDeskAcc æFc Desk.h æT Function æTN A9B7 æD pascal void CloseDeskAcc(short refNum) = 0xA9B7; æDT CloseDeskAcc((short) refNum); æRI I-440 æC When a system window is active and the user chooses Close from the File menu, call CloseDeskAcc to close the desk accessory. RefNum is the driver reference number for the desk accessory, which you get from the windowKind field of its window. The Desk Manager automatically closes a desk accessory if the user clicks its close box. Also, since the application heap is released when the application terminates, every desk accessory goes away at that time. æKY SystemClick æFc Desk.h æT Function æTN A9B3 æD pascal void SystemClick(const EventRecord *theEvent,WindowPtr theWindow) = 0xA9B3; æDT SystemClick((const EventRecord *) theEvent,(WindowPtr) theWindow); æMM æRI I-441, P-35, 182 æC When a mouse-down event occurs and the Window Manager function FindWindow reports that the mouse button was pressed in a system window, the application should call SystemClick with the event record and the window pointer. If the given window belongs to a desk accessory, SystemClick sees that the event gets handled properly. SystemClick determines which part of the desk accessory’s window the mouse button was pressed in, and responds accordingly (similar to the way your application responds to mouse activities in its own windows). • If the mouse button was pressed in the content region of the window and the window was active, SystemClick sends the mouse-down event to the desk accessory, which processes it as appropriate. • If the mouse button was pressed in the content region and the window was inactive, SystemClick makes it the active window. • If the mouse button was pressed in the drag region, SystemClick calls the Window Manager procedure DragWindow to pull an outline of the window across the screen and move the window to a new location. If the window was inactive, DragWindow also makes it the active window (unless the Command key was pressed along with the mouse button). • If the mouse button was pressed in the go-away region, SystemClick calls the Window Manager function TrackGoAway to determine whether the mouse is still inside the go-away region when the click is completed: If so, it tells the desk accessory to close itself; otherwise, it does nothing. æKY SystemEdit æFc Desk.h æT Function æTN A9C2 æD pascal Boolean SystemEdit(short editCmd) = 0xA9C2; æDT Boolean myVariable = SystemEdit((short) editCmd); æMM æRT 180, 215 æRI I-441 æC Assembly-language note: The macro you invoke to call SystemEdit from assembly language is named _SysEdit. Call SystemEdit when there’s a mouse-down event in the menu bar and the user chooses one of the five standard editing commands from the Edit menu. Pass one of the following as the value of the editCmd parameter: editCmd Editing command 0 Undo 2 Cut 3 Copy 4 Paste 5 Clear If your Edit menu contains these five commands in the standard arrangement (the order listed above, with a dividing line between Undo and Cut), you can simply call SystemEdit(menuItem-1) where menuItem is the menu item number. If the active window doesn’t belong to a desk accessory, SystemEdit returns FALSE; the application should then process the editing command as usual. If the active window does belong to a desk accessory, SystemEdit asks that accessory to process the command and returns TRUE; in this case, the application should ignore the command. Note: It’s up to the application to make sure desk accessories get their editing commands that are chosen from the Edit menu. In particular, make sure your application hasn’t disabled the Edit menu or any of the five standard commands when a desk accessory is activated. æKY SystemTask æFc Desk.h æT Function æTN A9B4 æD pascal void SystemTask(void) = 0xA9B4; æDT SystemTask()(void); æRT 85 æRI I-442, 444, II-189, N85-1 æC For each open desk accessory (or other device driver performing periodic actions), SystemTask causes the accessory to perform the periodic action defined for it, if any such action has been defined and if the proper time period has passed since the action was last performed. For example, a clock accessory can be defined such that the second hand is to move once every second; the periodic action for the accessory will be to move the second hand to the next position, and SystemTask will alert the accessory every second to perform that action. You should call SystemTask as often as possible, usually once every time through your main event loop. Call it more than once if your application does an unusually large amount of processing each time through the loop. Note: SystemTask should be called at least every sixtieth of a second. æKY SystemEvent æFc Desk.h æT Function æTN A9B2 æD pascal Boolean SystemEvent(const EventRecord *theEvent) = 0xA9B2; æDT Boolean myVariable = SystemEvent((const EventRecord *) theEvent); æRT 5,85 æRI I-442, N5-1, N85-1 æC SystemEvent is called only by the Toolbox Event Manager function GetNextEvent when it receives an event, to determine whether the event should be handled by the application or by the system. If the given event should be handled by the application, SystemEvent returns FALSE; otherwise, it calls the appropriate system code to handle the event and returns TRUE. In the case of a null or mouse-down event, SystemEvent does nothing but return FALSE. Notice that it responds this way to a mouse-down event even though the event may in fact have occurred in a system window (and therefore may have to be handled by the system). The reason for this is that the check for exactly where the event occurred (via the Window Manager function FindWindow) is made later by the application and so would be made twice if SystemEvent were also to do it. To avoid this duplication, SystemEvent passes the event on to the application and lets it make the sole call to FindWindow. Should FindWindow reveal that the mouse-down event did occur in a system window, the application can then call SystemClick, as described above, to get the system to handle it. If the given event is a mouse-up or any keyboard event (including keyboard equivalents of commands), SystemEvent checks whether the active window belongs to a desk accessory and whether that accessory can handle this type of event. If so, it sends the event to the desk accessory and returns TRUE; otherwise, it returns FALSE. If SystemEvent is passed an activate or update event, it checks whether the window the event occurred in is a system window belonging to a desk accessory and whether that accessory can handle this type of event. If so, it sends the event to the desk accessory and returns TRUE; otherwise, it returns FALSE. Note: It’s unlikely that a desk accessory would not be set up to handle keyboard, activate, and update events, or that it would handle mouse-up events. If the given event is a disk-inserted event, SystemEvent does some low-level processing (by calling the File Manager function MountVol) but passes the event on to the application by returning FALSE, in case the application wants to do further processing. Finally, SystemEvent returns FALSE for network, device driver, and application-defined events. Assembly-language note: Advanced programmers can make SystemEvent always return FALSE by setting the global variable SEvtEnb (a byte) to 0. æKY SystemMenu æFc Desk.h æT Function æTN A9B5 æD pascal void SystemMenu(long menuResult) = 0xA9B5; æDT SystemMenu((long) menuResult); æMM æRI I-443 æC SystemMenu is called only by the Menu Manager functions MenuSelect and MenuKey, when an item in a menu belonging to a desk accessory has been chosen. The menuResult parameter has the same format as the value returned by MenuSelect and MenuKey: the menu ID in the high-order word and the menu item number in the low-order word. (The menu ID will be negative.) SystemMenu directs the desk accessory to perform the appropriate action for the given menu item. æKY opendeskacc æFc Desk.h æT Function æD short opendeskacc(char *theAcc); æDT short myVariable = opendeskacc((char *) theAcc); æMM æRI I-440 æC OpenDeskAcc opens the desk accessory having the given name and displays its window (if any) as the active window. The name is the accessory’s resource name, which you get from the Apple menu by calling the Menu Manager procedure GetItem. OpenDeskAcc calls the Resource Manager to read the desk accessory from the resource file into the application heap. You should ignore the value returned by OpenDeskAcc. If the desk accessory is successfully opened, the function result is its driver reference number. However, if the desk accessory can’t be opened, the function result is undefined; the accessory will have taken care of informing the user of the problem (such as memory full) and won’t display itself. Warning: Early versions of some desk accessories may set the current grafPort to the accessory’s port upon return from OpenDeskAcc. To be safe, you should bracket your call to OpenDeskAcc with calls to the QuickDraw procedures GetPort and SetPort, to save and restore the current port. Note: Programmers concerned about the amount of available memory should be aware that an open desk accessory uses from 1K to 3K bytes of heap space in addition to the space needed for the accessory itself. The desk accessory is responsible for determining whether there is sufficient memory for it to run; this can be done by calling SizeResource followed by ResrvMem. æKY DeskBus.h æKL ADBOp ADBReInit CountADBs GetADBInfo GetIndADB SetADBInfo ADBAddress ADBDataBlock ADBDBlkPtr ADBOpBlock ADBOpBPtr ADBSetInfoBlock ADBSInfoPtr æKY ADBAddress æFc DeskBus.h æT typedef æD typedef char ADBAddress; æC æKY ADBOpBlock ADBOpBPtr æFc DeskBus.h æT struct æD struct ADBOpBlock { Ptr dataBuffPtr; /*address of data buffer*/ Ptr opServiceRtPtr; /*service routine pointer*/ Ptr opDataAreaPtr; /*optional data area address*/ }; typedef struct ADBOpBlock ADBOpBlock; typedef ADBOpBlock *ADBOpBPtr; æC æKY ADBDataBlock ADBDBlkPtr æFc DeskBus.h æT struct æD struct ADBDataBlock { char devType; /*device type*/ char origADBAddr; /*original ADB Address*/ Ptr dbServiceRtPtr; /*service routine pointer*/ Ptr dbDataAreaAddr; /*data area address*/ }; typedef struct ADBDataBlock ADBDataBlock; typedef ADBDataBlock *ADBDBlkPtr; æC æKY ADBSetInfoBlock ADBSInfoPtr æFc DeskBus.h æT struct æD struct ADBSetInfoBlock { Ptr siServiceRtPtr; /*service routine pointer*/ Ptr siDataAreaAddr; /*data area address*/ }; typedef struct ADBSetInfoBlock ADBSetInfoBlock; typedef ADBSetInfoBlock *ADBSInfoPtr; æC æKY ADBReInit æFc DeskBus.h æT Function æTN A07B æD pascal void ADBReInit(void) = 0xA07B; æDT ADBReInit()(void); æMM æRT 143, 206 æRI V-367, N143 æC Trap macro _ADBReInit ADBReInit reinitializes the entire Apple Desktop Bus. It clears the ADB device table to zeros and places a SendReset command on the bus to reset all devices to their original addresses. ADBReInit has no parameters. Because it does not deallocate ADB resources on the system heap, ADBReInit should not be used for routine bus initialization. Apple strongly recommends against adding devices while the system is running; therefore, you should never call ADBReInit. ADBReInit also calls a routine pointed to by the low memory global JADBProc at the beginning and end of its execution. You can insert your own preprocessing/postprocessing routine by changing the value of JADBProc; ADBReInit conditions it by setting D0 to 0 for preprocessing and to 1 for postprocessing. Your procedure must restore the value of D0 and branch to the original value of JADBProc on exit. JADBProc should be used to de-allocate memory used by the driver (see MacDTS Sample Code “TbltDrvr” for an example), and then it should chain to the procedure originally found in JADBProc. The complete ADBReInit sequence is therefore the following: • JSR to JADBProc with D0 set to 0 • reinitialize the Apple Desktop Bus • clear the ADB device table • JSR to JADBProc with D0 set to 1 æKY ADBOp æFc DeskBus.h æT Function æD pascal OSErr ADBOp(Ptr data,ProcPtr compRout,Ptr buffer,short commandNum); æDT OSErr myVariable = ADBOp((Ptr) data,(ProcPtr) compRout,(Ptr) buffer,(short) commandNum); æRT 206 æRI V-368 æC Trap macro _ADBOp On entry: A0: pointer to parameter block D0: commandNum (byte) Parameter block --> 0 buffer pointer --> 4 compRout pointer --> 8 data pointer On exit: D0: result code (byte) The completion routine pointed to by compRout will be passed the following parameters on entry: D0: commandNum (byte) A0: pointer to buffer, data stored as a Pascal string (maximum 8 bytes data preceded by one length byte) A1: pointer to completion routine (compRout) A2: pointer to optional data area (data) ADBOp transmits over the bus the command byte whose value is given by commandNum. The structure of the command byte is given earlier in Figure 1. ADBOp executes only when the ADB is otherwise idle; otherwise it is held in a command queue. It returns an error if the command queue is full. The length of the data buffer pointed to by buffer is contained in its first byte, like a Pascal string. The optional data area pointed to by data is for local storage by the completion routine pointed to by compRout. ADBop should be used sparingly; it is not intended for polling a device. The host automatically polls devices with data to deliver. Result codes noErr No error –1 Unsuccessful completion æKY CountADBs æFc DeskBus.h æT Function æD pascal short CountADBs(void); æDT short myVariable = CountADBs()(void); æRT 206 æRI V-369 æC Trap macro _CountADBs On exit: D0: number of devices (byte) CountADBs returns a value representing the number of devices connected to the ADB by counting the number of entries in the device table. It has no arguments and returns no error codes. æKY GetIndADB æFc DeskBus.h æT Function æD pascal ADBAddress GetIndADB(ADBDataBlock *info,short devTableIndex); æDT ADBAddress myVariable = GetIndADB((ADBDataBlock *) info,(short) devTableIndex); æRT 206 æRI V-369 æC Trap macro _GetIndADB On entry: A0: pointer to parameter block D0: entry index number; range = 1..CountADBs (byte) Parameter block <-- 0 device type byte (handler ID) <-- 1 original ADB address byte <-- 2 service routine address pointer (compRout) <-- 6 data area address pointer (data) On exit: D0: positive value: current ADB address (byte) negative value: error code (byte) GetIndADB returns information from the ADB device table entry whose index number is given by devTableIndex. ADBDataBlock has this form: TYPE ADBDataBlock = PACKED RECORD devType: SignedByte; {device type (handler ID)} origADBAddr: SignedByte; {original ADB address} dbServiceRtPtr: Ptr; {service routine address (compRout)} dbDataAreaAddr: Ptr {data area address (data)} END; GetIndADB returns the current ADB address of the device. If it is unable to complete execution successfully, GetIndADB returns a negative value. æKY GetADBInfo æFc DeskBus.h æT Function æD pascal OSErr GetADBInfo(ADBDataBlock *info,ADBAddress adbAddr); æDT OSErr myVariable = GetADBInfo((ADBDataBlock *) info,(ADBAddress) adbAddr); æRI V-370 æC Trap macro _GetADBInfo On entry: A0: pointer to parameter block D0: ADB address of the device (byte) Parameter block <-- 0 device handler ID byte <-- 1 original ADB address byte <-- 2 service routine address pointer (compRout) <-- 6 data area address pointer (data) On exit: D0: result code (byte) GetADBInfo returns information from the ADB device table entry of the device whose ADB address is given by ABDAddr. The structure of ADBDataBlock is given above under “GetIndADB”. Result codes noErr No error æKY SetADBInfo æFc DeskBus.h æT Function æD pascal OSErr SetADBInfo(ADBSetInfoBlock *info,ADBAddress adbAddr); æDT OSErr myVariable = SetADBInfo((ADBSetInfoBlock *) info,(ADBAddress) adbAddr); æRT 206 æRI V-370 æC Trap macro _SetADBInfo On entry: A0: pointer to parameter block D0: ADB address of the device (byte) Parameter block --> 0 service routine address pointer (compRout) --> 4 data area address pointer (data) On exit: D0: result code (byte) SetADBInfo sets the service routine address and the data area address in the ADB device table entry for the device whose ADB address is given by ABDAddr. ADBSetInfoBlock has this form: TYPE ADBSetInfoBlock = RECORD siServiceRtPtr: Ptr; {service routine address (compRout)} siDataAreaAddr: Ptr {data area address (data)} END; Result codes noErr No error Warning: You should send a Flush command to the device after calling it with SetADBInfo, to prevent it sending old data to the new data area address. æKY Devices.h æKL CloseDriver Control GetDCtlEntry KillIO opendriver OpenDriver PBControl PBKillIO PBStatus SetChooserAlert Status activDev AuxDCE AuxDCEHandle AuxDCEPtr buttonMsg cdevGenErr cdevMemErr cdevResErr cdevUnset chooserID clearDev closeDev copyDev cursorDev cutDev DCtlEntry DCtlHandle DCtlPtr deactivDev deselectMsg fillListMsg getSelMsg hitDev initDev keyEvtDev macDev newSelMsg nulDev pasteDev selectMsg terminateMsg undoDev updateDev æKY newSelMsg æFc Devices.h æT #define æD #define newSelMsg 12 æC æKY fillListMsg æFc Devices.h æT #define æD #define fillListMsg 13 æC æKY getSelMsg æFc Devices.h æT #define æD #define getSelMsg 14 æC æKY selectMsg æFc Devices.h æT #define æD #define selectMsg 15 æC æKY deselectMsg æFc Devices.h æT #define æD #define deselectMsg 16 æC æKY terminateMsg æFc Devices.h æT #define æD #define terminateMsg 17 æC æKY buttonMsg æFc Devices.h æT #define æD #define buttonMsg 19 æC æKY chooserID æFc Devices.h æT #define æD #define chooserID 1 æC æKY initDev æFc Devices.h æT #define æD #define initDev 0 /*Time for cdev to initialize itself*/ æC »The initDev Message InitDev is an initialization message sent to allow the cdev to allocate its private storage (if any) and do any initial settings to buttons or controls. This message is sent when the user clicks on the cdev’s icon. Note that the dialog, cdev list, and all of the items in the cdev’s 'DITL' except user items will already have been drawn when the initDev message is sent. If your cdev doesn’t need any storage it should return the value that was passed to it in cdevValue. æKY hitDev æFc Devices.h æT #define æD #define hitDev 1 /*Hit on one of my items*/ æC »The hitDev Message A hitDev message is sent when the user has clicked an enabled dialog item that belongs to the cdev. The dialog item number of the item hit is passed in the Item parameter. Remember that the Control Panel’s items precede yours, so you’ll want (Item – numItems) to determine which of your items was hit. If the Control Panel itself has n items, the first of the cdev’s items will be n+1 in the combined dialog item list. A cdev should not depend on any hardcoded value for numItems, since the number of items in Control Panel’s 'DITL' is likely to change in the future. Factoring in numItems need not mean an increase in your code size, or passing and adding numItems everywhere, or foregoing the constants that most developers use to identify specific items. You can do it easily, and neatly, as follows: 1. Subtract numItems from Item right away, and refer to your dialog items with constants as usual throughout the cdev. 2. Write simple envelope routines to enclose Dialog Manager procedures that require item number arguments. Add numItems only locally, within those routines and for the Dialog Manager calls only. This is demonstrated in the sample cdev. æKY closeDev æFc Devices.h æT #define æD #define closeDev 2 /*Close yourself*/ æC æKY nulDev æFc Devices.h æT #define æD #define nulDev 3 /*Null event*/ æC »The nulDev Message A nulDev message is sent to the cdev on every Control Panel run event. This allows the cdev to perform tasks that need to be executed continuously (insertion point blinking, for example). A cdev cannot assume any particular timing of calls from applications. Don’t use nulDev to refresh settings; see activDev, above. æKY updateDev æFc Devices.h æT #define æD #define updateDev 4 /*Update event*/ æC æKY activDev æFc Devices.h æT #define æD #define activDev 5 /*Activate event*/ æC #define activDev 5 /*Activate event*/ »The activDev Message An activDev message is sent to the cdev on every activate event. It allows the cdev to reset any items that may have changed while the Control Panel was inactive. It also allows the cdev to send things such as “lists activate” messages. æKY deactivDev æFc Devices.h æT #define æD #define deactivDev 6 /*Deactivate event*/ æC æKY keyEvtDev æFc Devices.h æT #define æD #define keyEvtDev 7 /*Key down/auto key*/ æC »The keyEvtDev Message A keyEvtDev message is sent to the cdev on every keyDown event and autoKey event. It allows the cdev to process key events. On return to the Control Panel, the key event will be processed by a call to dialogSelect in the Dialog Manager. A cdev that does not want the Toolbox Event Manager to do any further processing should change the what field of the EventRecord to nullEvent before returning to the Control Panel. æKY macDev æFc Devices.h æT #define æD #define macDev 8 /*Decide whether or not to show up*/ æC »The macDev Message If the 'mach' resource has a 0 in Softmask and a –1 ($FFFF) in Hardmask, the first message a cdev will get is a macDev message. This is an opportunity for the cdev to determine whether it can run, and whether it should appear in the Control Panel’s cdev list. The cdev can do its own check to see which machine it is being run on, what hardware is connected, and what is in the slots (if it has slots). The cdev must then return a function result of 1 or 0. If a 0 is returned, the Control Panel will not display the cdev in the icon list. (Note that the Control Panel does not interpret this 0 or 1 as an error message as described under “Cdev Error Checking”.) The macDev call happens only once, and only when Softmask and Hardmask are 0 and FFFF. It is always the first call made to the cdev. #define macDev 8 /*Decide whether or not to show up*/ æKY undoDev æFc Devices.h æT #define æD #define undoDev 9 æC æKY cutDev æFc Devices.h æT #define æD #define cutDev 10 æC æKY copyDev æFc Devices.h æT #define æD #define copyDev 11 æC æKY pasteDev æFc Devices.h æT #define æD #define pasteDev 12 æC æKY clearDev æFc Devices.h æT #define æD #define clearDev 13 æC æKY cursorDev æFc Devices.h æT #define æD #define cursorDev 14 æC æKY cdevGenErr æFc Devices.h æT #define æD #define cdevGenErr -1 /*General error; gray cdev w/o alert*/ æC æKY cdevMemErr æFc Devices.h æT #define æD #define cdevMemErr 0 /*Memory shortfall; alert user please*/ æC æKY cdevResErr æFc Devices.h æT #define æD #define cdevResErr 1 /*Couldn't get a needed resource; alert*/ æC æKY cdevUnset æFc Devices.h æT #define æD #define cdevUnset 3 /* cdevValue is initialized to this*/ æC »CDEV ERROR CHECKING _______________________________________________________________________________ Because a desk accessory may be called into many strange and wonderful situations, careful attention must be paid to error checking. The two most common error conditions are missing resources and lack of memory. Some error reporting and recovery facilities have been provided in the Control Panel to help with errors encountered in a cdev. Because the Control Panel has no direct information about the cdev, the cdev’s code must be able to detect and recover from error conditions on its own. If the recovery cannot be effected the cdev must dispose of any memory it has allocated, and exit back to the Control Panel with an error code. Following a shutdown, the Control Panel can help report the error condition to the user and prevent accidental reentry into the cdev that might result from such things as an update event. A cdev can request three different error reporting mechanisms from the Control Panel: • If a memory error has occured, then, after the cdev has safely shut itself down, it may request the Control Panel to issue an out-of-memory error message and gray out (paint over with the background pattern) the cdev area of the Control Panel window. It will remain grayed until another cdev is selected. The Control Panel window itself is not closed since other cdevs may still be able to function in the environment. • If a resource error is detected, the cdev may request that a can’t-find-needed-resource error message be issued. • The cdev may display its own error message and then call on the Control Panel to gray its area. The Control Panel uses the cdevValue parameter to send status information to the cdev, and a proper cdev uses its function value to send information back to the Control Panel. In the absence of errors, the same value passes back and forth: the Control Panel puts the last function value it received into cdevValue when it calls the cdev; the cdev returns the value it finds there as the function value. The cdev may want to keep a handle to its own storage, in which case passing it as the function value ensures its availability, since the Control Panel will pass it back in cdevValue at the next call. Four constants have been defined for this cdev/Control Panel communication: #define cdevUnset 3 /*initial value passed in cdevValue*/ #define cdevGenErr -1 /*generic cdev error*/ #define cdevMemErr 0 /*insufficient memory for cdev execution*/ #define cdevResErr 1 /*missing resource needed by cdev*/ After the macDev call, the Control Panel sends cdevUnset in cdevValue, so that until an error occurs or the cdev uses its function value as a handle, cdevUnset is passed back and forth. If the cdev encounters an error, it should dispose of all handles and pointers it has set up, strip the stack back to the same position as a normal exit, and return one of the three error codes as the function result. The Control Panel will respond as follows: Function Message to Control Panel Action Result Control Panel cdevGenErr The cdev has encountered an Gray out the cdev’s area, error from which it cannot send a 0 in cdevValue in recover, but do not put up succeeding cdev calls an error dialog. cdevMemErr The cdev has determined that Gray out cdev’s area, put there is not enough memory to up error dialog, send a 0 execute; please put up a in cdevValue in succeeding memory error dialog. cdev calls. cdevResErr The cdev can’t find a needed Gray out cdev’s area, put resource; please put up a up error dialog, send a 0 resource error dialog. in cdevValue in succeeding cdev calls. all other values, No error conditions. Send the value back in either handles cdevValue. or cdevUnset The cdev code should check cdevValue at entry. A 0 means that the Control Panel has responded to a cdev error message by shutting down the cdev and displaying an error dialog if one was requested. The cdev should immediately exit. Once the Control Panel has responded to an error message from a cdev it will no longer respond to any return values until another cdev is launched. æKY DCtlEntry DCtlPtr DCtlHandle æFc Devices.h æT struct æD struct DCtlEntry { Ptr dCtlDriver; short dCtlFlags; QHdr dCtlQHdr; long dCtlPosition; Handle dCtlStorage; short dCtlRefNum; long dCtlCurTicks; WindowPtr dCtlWindow; short dCtlDelay; short dCtlEMask; short dCtlMenu; }; typedef struct DCtlEntry DCtlEntry; typedef DCtlEntry *DCtlPtr, **DCtlHandle; æC »Device Control Entry The first time a driver is opened, information about it is read into a structure in memory called a device control entry. A device control entry contains the header of the driver’s I/O queue, the location of the driver’s routines, and other information. A device control entry is a 40-byte relocatable block located in the system heap. It’s locked while the driver is open, and unlocked while the driver is closed. Most of the data in the device control entry is stored and accessed only by the Device Manager, but in some cases the driver itself must store into it. The structure of a device control entry is shown below; note that the first four words of the driver are copied into the dCtlFlags, dCtlDelay, dCtlEMask, and dCtlMenu fields. TYPE DCtlEntry = RECORD dCtlDriver: Ptr; {pointer to ROM driver or } { handle to RAM driver} dCtlFlags: INTEGER; {flags} dCtlQHdr: QHdr; {driver I/O queue header} dCtlPosition: LONGINT; {byte position used by Read } { and Write calls} dCtlStorage: Handle; {handle to RAM driver's } { private storage} dCtlRefNum: INTEGER; {driver reference number} dCtlCurTicks: LONGINT; {used internally} dCtlWindow: WindowPtr; {pointer to driver's window} dCtlDelay: INTEGER; {number of ticks between } { periodic actions} dCtlEMask: INTEGER; {desk accessory event mask} dCtlMenu: INTEGER {menu ID of menu associated { with driver} END; DCtlPtr = ^DCtlEntry; DCtlHandle = ^DCtlPtr; The low-order byte of the dCtlFlags word contains the following flags: Bit number Meaning 5 Set if driver is open 6 Set if driver is RAM-based 7 Set if driver is currently executing Assembly-language note: These flags can be accessed with the global constants dOpened, dRAMBased, and drvrActive. The high-order byte of the dCtlFlags word contains flags copied from the drvrFlags word of the driver, as described above. DCtlQHdr contains the header of the driver’s I/O queue (described below). DCtlPosition is used only by drivers of block devices, and indicates the current source or destination position of a Read or Write call. The position is given as a number of bytes beyond the physical beginning of the medium used by the device. For example, if one logical block of data has just been read from a 3 1/2-inch disk via the Disk Driver, dCtlPosition will be 512. ROM drivers generally use locations in low memory for their local storage. RAM drivers may reserve memory within their code space, or allocate a relocatable block and keep a handle to it in dCtlStorage (if the block resides in the application heap, its handle will be set to NIL when the heap is reinitialized). You can get a handle to a driver’s device control entry by calling the Device Manager function GetDCtlEntry. æKY AuxDCE AuxDCEPtr AuxDCEHandle æFc Devices.h æT struct æD struct AuxDCE { Ptr dCtlDriver; short dCtlFlags; QHdr dCtlQHdr; long dCtlPosition; Handle dCtlStorage; short dCtlRefNum; long dCtlCurTicks; GrafPtr dCtlWindow; short dCtlDelay; short dCtlEMask; short dCtlMenu; char dCtlSlot; char dCtlSlotId; long dCtlDevBase; Ptr dCtlOwner; char dCtlExtDev; char fillByte; }; typedef struct AuxDCE AuxDCE; typedef AuxDCE *AuxDCEPtr, **AuxDCEHandle; æC æKY GetDCtlEntry æFc Devices.h æT Function æD pascal DCtlHandle GetDCtlEntry(short refNum); æDT DCtlHandle myVariable = GetDCtlEntry((short) refNum); æMM æRT 71 æRI II-190 æC æKY SetChooserAlert æFc Devices.h æT Function æD pascal Boolean SetChooserAlert(Boolean f); æDT Boolean myVariable = SetChooserAlert((Boolean) f); æRI V-431 æC If f is true, the Chooser will put up the page setup alert; if f is false it won’t. SetChooserAlert returns the original alert state. The application should restore the original alert state when it exits. _____________________________________________________________________________________ Assembly-language note: If the psAlert bit of the low-memory global HiliteMode is 0 then no page setup alert will be generated. Applications that set or clear this bit must be sure not to affect any other bits in the byte and to restore the bit as they leave. HiliteMode equ $938 psAlert equ 6 bclr #psAlert,HiliteMode bset #psAlert,HiliteMode _____________________________________________________________________________________ æKY OpenDriver æFc Devices.h æT Function æD pascal OSErr OpenDriver(const Str255 name,short *drvrRefNum); æDT OSErr myVariable = OpenDriver((const Str255) name,(short *) drvrRefNum); æMM æRI II-178, N14-2 æC [Not in ROM] OpenDriver opens the device driver specified by name and returns its reference number in refNum. Result codes noErr No error badUnitErr Bad reference number dInstErr Couldn’t find driver in resource file openErr Driver can’t perform the requested reading or writing unitEmptyErr Bad reference number æKY opendriver æFc Devices.h æT Function æD OSErr opendriver(char *driverName,short *refNum); æDT OSErr myVariable = opendriver((char *) driverName,(short *) refNum); æC æKY CloseDriver æFc Devices.h æT Function æD pascal OSErr CloseDriver(short refNum); æDT OSErr myVariable = CloseDriver((short) refNum); æRI II-178 æC [Not in ROM] CloseDriver closes the device driver having the reference number refNum. Any pending I/O is completed, and the memory used by the driver is released. Warning: Before using this command to close a particular driver, refer to the chapter describing the driver for the consequences of closing it. Result codes noErr No error badUnitErr Bad reference number dRemoveErr Attempt to remove an open driver unitEmptyErr Bad reference number æKY Control æFc Devices.h æT Function æD pascal OSErr Control(short refNum,short csCode,Ptr csParamPtr); æDT OSErr myVariable = Control((short) refNum,(short) csCode,(Ptr) csParamPtr); æMM æRI II-186 æC [Not in ROM] Control sends control information to the device driver having the reference number refNum. The type of information sent is specified by csCode, and the information itself is pointed to by csParamPtr. The values passed in csCode and pointed to by csParamPtr depend on the driver being called. Result codes noErr No error badUnitErr Bad reference number notOpenErr Driver isn’t open unitEmptyErr Bad reference number controlErr Driver can’t respond to this Control call æKY Status æFc Devices.h æT Function æD pascal OSErr Status(short refNum,short csCode,Ptr csParamPtr); æDT OSErr myVariable = Status((short) refNum,(short) csCode,(Ptr) csParamPtr); æMM æRI II-186 æC [Not in ROM] Status returns status information about the device driver having the reference number refNum. The type of information returned is specified by csCode, and the information itself is pointed to by csParamPtr. The values passed in csCode and pointed to by csParamPtr depend on the driver being called. Result codes noErr No error badUnitErr Bad reference number notOpenErr Driver isn’t open unitEmptyErr Bad reference number statusErr Driver can’t respond to this Status call æKY KillIO æFc Devices.h æT Function æD pascal OSErr KillIO(short refNum); æDT OSErr myVariable = KillIO((short) refNum); æRI II-179 æC [Not in ROM] KillIO terminates all current and pending I/O with the device driver having the reference number refNum. Result codes noErr No error badUnitErr Bad reference number æKY PBControl æFc Devices.h æT Function æD pascal OSErr PBControl(ParmBlkPtr paramBlock,Boolean aSync); æDT OSErr myVariable = PBControl((ParmBlkPtr) paramBlock,(Boolean) aSync); æMM æRI II-186 æC Trap macro _Control Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 22 ioVRefNum word --> 24 ioRefNum word --> 26 csCode word --> 28 csParam record PBControl sends control information to the device driver having the reference number ioRefNum; the drive number, if any, is specified by ioVRefNum. The type of information sent is specified by csCode, and the information itself begins at csParam. The values passed in csCode and csParam depend on the driver being called. Result codes noErr No error badUnitErr Bad reference number notOpenErr Driver isn’t open unitEmptyErr Bad reference number controlErr Driver can’t respond to this Control call æKY PBStatus æFc Devices.h æT Function æD pascal OSErr PBStatus(ParmBlkPtr paramBlock,Boolean aSync); æDT OSErr myVariable = PBStatus((ParmBlkPtr) paramBlock,(Boolean) aSync); æMM æRI II-186 æC Trap macro _Status Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 22 ioVRefNum word --> 24 ioRefNum word --> 26 csCode word <-- 28 csParam record PBStatus returns status information about the device driver having the reference number ioRefNum; the drive number, if any, is specified by ioVRefNum. The type of information returned is specified by csCode, and the information itself begins at csParam. The values passed in csCode and csParam depend on the driver being called. Result codes noErr No error badUnitErr Bad reference number notOpenErr Driver isn’t open unitEmptyErr Bad reference number statusErr Driver can’t respond to this Status call æKY PBKillIO æFc Devices.h æT Function æD pascal OSErr PBKillIO(ParmBlkPtr paramBlock,Boolean aSync); æDT OSErr myVariable = PBKillIO((ParmBlkPtr) paramBlock,(Boolean) aSync); æRI II-187 æC Trap macro _KillIO Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word PBKillIO stops any current I/O request being processed, and removes all pending I/O requests from the I/O queue of the device driver having the reference number ioRefNum. The completion routine of each pending I/O request is called, with the ioResult field of each request equal to the result code abortErr. Result codes noErr No error badUnitErr Bad reference number unitEmptyErr Bad reference number æKY Dialogs.h æKL Alert CautionAlert CloseDialog CouldAlert CouldDialog DialogSelect DisposDialog DlgCopy DlgCut DlgDelete DlgPaste DrawDialog ErrorSound findditem FindDItem FreeAlert FreeDialog GetAlrtStage GetDItem getitext GetIText GetNewDialog HideDItem InitDialogs IsDialogEvent ModalDialog newcdialog NewCDialog newdialog NewDialog NoteAlert paramtext ParamText ResetAlrtStage SelIText SetDAFont SetDItem setitext SetIText ShowDItem StopAlert UpdtDialog AlertTemplate AlertTHndl AlertTPtr btnCtrl cancel cautionIcon chkCtrl ctrlItem DialogPeek DialogPtr DialogRecord DialogTemplate DialogTHndl DialogTPtr editText iconItem itemDisable noteIcon ok picItem radCtrl resCtrl ResumeProcPtr SoundProcPtr StageList statText stopIcon userItem æKY ctrlItem æFc Dialogs.h æT #define æD #define ctrlItem 4 æC æKY btnCtrl æFc Dialogs.h æT #define æD #define btnCtrl 0 æC æKY chkCtrl æFc Dialogs.h æT #define æD #define chkCtrl 1 æC æKY radCtrl æFc Dialogs.h æT #define æD #define radCtrl 2 æC æKY resCtrl æFc Dialogs.h æT #define æD #define resCtrl 3 æC æKY statText æFc Dialogs.h æT #define æD #define statText 8 æC æKY editText æFc Dialogs.h æT #define æD #define editText 16 æC æKY iconItem æFc Dialogs.h æT #define æD #define iconItem 32 æC æKY picItem æFc Dialogs.h æT #define æD #define picItem 64 æC æKY userItem æFc Dialogs.h æT #define æD #define userItem 0 æC æKY itemDisable æFc Dialogs.h æT #define æD #define itemDisable 128 æC æKY ok æFc Dialogs.h æT #define æD #define ok 1 æC æKY cancel æFc Dialogs.h æT #define æD #define cancel 2 æC æKY stopIcon æFc Dialogs.h æT #define æD #define stopIcon 0 æC æKY noteIcon æFc Dialogs.h æT #define æD #define noteIcon 1 æC æKY cautionIcon æFc Dialogs.h æT #define æD #define cautionIcon 2 æC æKY StageList æFc Dialogs.h æT typedef æD typedef short StageList; æC »Alert Templates in Memory The data structure of an alert template is as follows: TYPE AlertTemplate = RECORD boundsRect: Rect; {becomes window's portRect} itemsID: INTEGER; {resource ID of item list} stages: StageList {alert stage information} END; BoundsRect is the rectangle that becomes the portRect of the window's grafPort. The itemsID field contains the resource ID of the item list for the alert. The information in the stages field determines exactly what should happen at each stage of the alert. It's packed into a word that has the following structure: TYPE StageList = PACKED RECORD boldItm4: 0..1; {default button item number minus 1} boxDrwn4: BOOLEAN; {TRUE if alert box to be drawn} sound4: 0..3 {sound number} boldItm3: 0..1; boxDrwn3: BOOLEAN; sound3: 0..3 boldItm2: 0..1; boxDrwn2: BOOLEAN; sound2: 0..3 boldItm1: 0..1; boxDrwn1: BOOLEAN; sound1: 0..3 END; Notice that the information is stored in reverse order—for the fourth stage first, and for the first stage last. The boldItm field indicates which button should be the default button (and therefore boldly outlined in the alert box). If the first two items in the alert’s item list are the OK button and the Cancel button, respectively, 0 will refer to the OK button and 1 to the Cancel button. The reason for this is that the value of boldItm plus 1 is interpreted as an item number, and normally items 1 and 2 are the OK and Cancel buttons, respectively. Whatever the item having the corresponding item number happens to be, a bold rounded-corner rectangle will be drawn outside its display rectangle. Note: When deciding where to place items in an alert box, be sure to allow room for any bold outlines that may be drawn. The boxDrwn field is TRUE if the alert box is to be drawn. The sound field specifies which sound should be emitted at this stage of the alert, with a number from 0 to 3 that’s passed to the current sound procedure. You can call ErrorSound to specify your own sound procedure; if you don’t, the standard sound procedure will be used (as described earlier in the “Alerts” section). You access the alert template by converting the handle returned by the Resource Manager to a template handle: TYPE AlertTHndl = ^AlertTPtr; AlertTPtr = ^AlertTemplate; Assembly-language note: Rather than offsets into the fields of the StageList data structure, there are masks for accessing the information stored for an alert stage in a stages word; they’re listed in the summary at the end of this chapter. æKY DialogPtr æFc Dialogs.h æT typedef æD typedef WindowPtr DialogPtr; æC »Dialog Pointers There are two types of dialog pointer, DialogPtr and DialogPeek, analogous to the window pointer types WindowPtr and WindowPeek. Most programmers will only need to use DialogPtr. The Dialog Manager defines the following type of dialog pointer: TYPE DialogPtr = WindowPtr; It can do this because the first field of a dialog record contains the window record for the dialog window. This type of pointer can be used to access fields of the window record or can be passed to Window Manager routines that expect window pointers as parameters. Since the WindowPtr data type is itself defined as GrafPtr, this type of dialog pointer can also be used to access fields of the dialog window’s grafPort or passed to QuickDraw routines that expect pointers to grafPorts as parameters. For programmers who want to access dialog record fields beyond the window record, the Dialog Manager also defines the following type of dialog pointer: TYPE DialogPeek = ^DialogRecord; Assembly-language note: From assembly language, of course, there’s no type checking on pointers, and the two types of pointer are equal. _______________________________________________________________________________ »The DialogRecord Data Type For those who want to know more about the data structure of a dialog record, the exact structure is given here. TYPE DialogRecord = RECORD window: WindowRecord; {dialog window} items: Handle; {item list} textH: TEHandle; {current editText item} editField: INTEGER; {editText item number minus 1} editOpen: INTEGER; {used internally} aDefItem: INTEGER {default button item number} END; The window field contains the window record for the dialog window. The items field contains a handle to the item list used for the dialog. (Remember that after reading an item list from a resource file, the Dialog Manager makes a copy of it and uses that copy.) Note: To get or change information about an item in a dialog, you pass the dialog pointer and the item number to a Dialog Manager procedure. You’ll never access information directly through the handle to the item list. The Dialog Manager uses the next three fields when there are one or more editText items in the dialog. If there’s more than one such item, these fields apply to the one that currently is selected or displays the insertion point. The textH field contains the handle to the edit record used by TextEdit. EditField is 1 less than the item number of the current editText item, or –1 if there’s no editText item in the dialog. The editOpen field is used internally by the Dialog Manager. Note: Actually, a single edit record is shared by all editText items; any changes you make to it will apply to all such items. See the TextEdit chapter for details about what kinds of changes you can make. The aDefItem field is used for modal dialogs and alerts, which are treated internally as special modal dialogs. It contains the item number of the default button. The default button for a modal dialog is the first item in the item list, so this field contains 1 for modal dialogs. The default button for an alert is specified in the alert template; see the following section for more information. _______________________________________________________________________________ »THE DRAWING ENVIRONMENT: GRAFPORT _______________________________________________________________________________ A grafPort is a complete drawing environment that defines where and how graphic operations will take place. You can have many grafPorts open at once, and each one will have its own coordinate system, drawing pattern, background pattern, pen size and location, character font and style, and bit map in which drawing takes place. You can instantly switch from one port to another. GrafPorts are the structures upon which a program builds windows, which are fundamental to the Macintosh “overlapping windows” user interface. Besides being used for windows on the screen, grafPorts are used for printing and for off-screen drawing. A grafPort is defined as follows: TYPE GrafPtr = ^GrafPort; GrafPort = RECORD device: INTEGER; {device-specific information} portBits: BitMap; {grafPort's bit map} portRect: Rect; {grafPort's rectangle} visRgn: RgnHandle; {visible region} clipRgn: RgnHandle; {clipping region} bkPat: Pattern; {background pattern} fillPat: Pattern; {fill pattern} pnLoc: Point; {pen location} pnSize: Point; {pen size} pnMode: INTEGER; {pen's transfer mode} pnPat: Pattern; {pen pattern} pnVis: INTEGER; {pen visibility} txFont: INTEGER; {font number for text} txFace: Style; {text's character style} txMode: INTEGER; {text's transfer mode} txSize: INTEGER; {font size for text} spExtra: Fixed; {extra space} fgColor: LONGINT; {foreground color} bkColor: LONGINT; {background color} colrBit: INTEGER; {color bit} patStretch: INTEGER; {used internally} picSave: Handle; {picture being saved} rgnSave: Handle; {region being saved} polySave: Handle; {polygon being saved} grafProcs: QDProcsPtr {low-level drawing routines} END; Note that picSave is a Handle used internally by QuickDraw while it is saving a picture, and rgnSave and polySave are used by QuickDraw as flags; they are set to “1” when the corresponding action is taking place. All QuickDraw operations refer to grafPorts via grafPtrs. (For historical reasons, grafPort is one of the few objects in the Macintosh system software that’s referred to by a pointer rather than a handle.) Warning: You can access all fields and subfields of a grafPort normally, but you should not store new values directly into them. QuickDraw has routines for altering all fields of a grafPort, and using these routines ensures that changing a grafPort produces no unusual side effects. The device field of a grafPort contains device-specific information that’s used by the Font Manager to achieve the best possible results when drawing text in the grafPort. There may be physical differences in the same logical font for different output devices, to ensure the highest-quality printing on the device being used. The default value of the device field is 0, for best results on output to the screen. For more information, see the Font Manager chapter. The portBits field is the bit map that points to the bit image to be used by the grafPort. The default bit map uses the entire screen as its bit image. The bit map may be changed to indicate a different structure in memory: All graphics routines work in exactly the same way regardless of whether their effects are visible on the screen. A program can, for example, prepare an image to be printed on a printer without ever displaying the image on the screen, or develop a picture in an off-screen bit map before transferring it to the screen. The portBits.bounds rectangle determines the coordinate system of the grafPort; all other coordinates in the grafPort are expressed in this system. The portRect field is a rectangle that defines a subset of the bit map that will be used for drawing: All drawing done by the application occurs inside the portRect. Its coordinates are in the coordinate system defined by the portBits.bounds rectangle. The portRect usually falls within the portBits.bounds rectangle, but it’s not required to do so. The portRect usually defines the “writable” interior area of a window, document, or other object on the screen. The visRgn field is manipulated by the Window Manager; you will normally never change a grafPort’s visRgn. It indicates the region of the grafPort that’s actually visible on the screen, that is, the part of the window that’s not covered by other windows. For example, if you move one window in front of another, the Window Manager logically removes the area of overlap from the visRgn of the window in back. When you draw into the back window, whatever’s being drawn is clipped to the visRgn so that it doesn’t run over onto the front window. The default visRgn is set to the portRect. The clipRgn is the grafPort’s clipping region, an arbitrary region that you can use to limit drawing to any region within the portRect. If, for example, you want to draw a half circle on the screen, you can set the clipRgn to half the square that would enclose the whole circle, and then draw the whole circle. Only the half within the clipRgn will actually be drawn in the grafPort. The default clipRgn is set arbitrarily large, you have full control over its setting; as a matter of recommended programming practice, it is advisable to make the default clipRgn rectangle smaller. Figure 10 illustrates a typical bit map (as defined by portBits), portRect, visRgn, and clipRgn. •••Refer to Figure 10.••• Figure 10–GrafPort Regions The bkPat and fillPat fields of a grafPort contain patterns used by certain QuickDraw routines. BkPat is the “background” pattern that’s used when an area is erased or when bits are scrolled out of it. When asked to fill an area with a specified pattern, QuickDraw stores the given pattern in the fillPat field and then calls a low-level drawing routine that gets the pattern from that field. The various graphic operations are discussed in detail later in the descriptions of individual QuickDraw routines. Of the next ten fields, the first five determine characteristics of the graphics pen and the last five determine characteristics of any text that may be drawn; these are described in separate sections below. The fgColor, bkColor, and colrBit fields contain values related to drawing in color. FgColor is the grafPort’s foreground color and bkColor is its background color. ColrBit tells the color imaging software which plane of the color picture to draw into. For more information, see “Drawing in Color” in the section “General Discussion of Drawing”. The patStretch field is used during output to a printer to expand patterns if necessary. The application should not change its value. The picSave, rgnSave, and polySave fields reflect the state of picture, region, and polygon definition, respectively. The application shouldn’t be concerned about exactly what information the handle, if any, leads to; you may, however, save the current value of rgnSave, set the field to NIL to disable the region definition, and later restore it to the saved value to resume the region definition. The picSave and polySave fields work similarly for pictures and polygons. Finally, the grafProcs field may point to a special data structure that the application stores into if it wants to customize QuickDraw drawing routines or use QuickDraw in other advanced, highly specialized ways (see “Customizing QuickDraw Operations”). If grafProcs is NIL, QuickDraw responds in the standard ways described in this chapter. _______________________________________________________________________________ »Pen Characteristics The pnLoc, pnSize, pnMode, pnPat, and pnVis fields of a grafPort deal with the graphics “pen”. Each grafPort has one and only one such pen, which is used for drawing lines, shapes, and text. The pen has four characteristics: a location, a size (height and width), a drawing mode, and a drawing pattern (see Figure 11). •••Refer to Figure 11.••• Figure 11–A Graphics Pen The pnLoc field specifies the point where QuickDraw will begin drawing the next line, shape, or character. It can be anywhere on the coordinate plane: There are no restrictions on the movement or placement of the pen. Remember that the pen location is a point in the grafPort’s coordinate system, not a pixel in a bit image. The top left corner of the pen is at the pen location; the pen hangs below and to the right of this point. The pen is rectangular in shape, and its width and height are specified by pnSize. The default size is a 1-by-1-bit square; the width and height can range from (0,0) to (30000,30000). If either the pen width or the pen height is less than 1, the pen will not draw. The pnMode and pnPat fields of a grafPort determine how the bits under the pen are affected when lines or shapes are drawn. The pnPat is a pattern that’s used like the “ink” in the pen. This pattern, like all other patterns drawn in the grafPort, is always aligned with the port’s coordinate system: The top left corner of the pattern is aligned with the top left corner of the portRect, so that adjacent areas of the same pattern will blend into a continuous, coordinated pattern. The pnMode field determines how the pen pattern is to affect what’s already in the bit image when lines or shapes are drawn. When the pen draws, QuickDraw first determines what bits in the bit image will be affected and finds their corresponding bits in the pattern. It then does a bit-by-bit comparison based on the pen mode, which specifies one of eight Boolean operations to perform. The resulting bit is stored into its proper place in the bit image. The pen modes are described under “Transfer Modes” in the section “General Discussion of Drawing”. The pnVis field determines the pen’s visibility, that is, whether it draws on the screen. For more information, see the descriptions of HidePen and ShowPen under “Pen and Line-Drawing Routines” in the “QuickDraw Routines” section. _______________________________________________________________________________ »Text Characteristics The txFont, txFace, txMode, txSize, and spExtra fields of a grafPort determine how text will be drawn—the font, style, and size of characters and how they will be placed in the bit image. QuickDraw can draw characters as quickly and easily as it draws lines and shapes, and in many prepared fonts. Font means the complete set of characters of one typeface. The characters may be drawn in any size and character style (that is, with stylistic variations such as bold, italic, and underline). Figure 12 shows two characters drawn by QuickDraw and some terms associated with drawing text. •••Refer to Figure 12.••• Figure 12–QuickDraw Characters Text is drawn with the base line positioned at the pen location. The txFont field is a font number that identifies the character font to be used in the grafPort. The font number 0 represents the system font. For more information about the system font, the other font numbers recognized by the Font Manager, and the construction, layout, and loading of fonts, see the Font Manager chapter. A character font is defined as a collection of images that make up the individual characters of the font. The characters can be of unequal widths, and they’re not restricted to their “cells”: The lower curl of a lowercase j, for example, can stretch back under the previous character (typographers call this kerning). A font can consist of up to 255 distinct characters, yet not all characters need to be defined in a single font. In addition, each font contains a missing symbol to be drawn in case of a request to draw a character that’s missing from the font. The txFace field controls the character style of the text with values from the set defined by the Style data type: TYPE StyleItem = (bold,italic,underline,outline,shadow,condense,extend); Style = SET OF StyleItem; Assembly-language note: In assembly language, this set is stored as a word whose low-order byte contains bits representing the style. The bit numbers are specified by the following global constants: boldBit .EQU 0 italicBit .EQU 1 ulineBit .EQU 2 outlineBit .EQU 3 shadowBit .EQU 5 extendBit .EQU 6 If all bits are 0, it represents the plain character style. You can apply stylistic variations either alone or in combination; Figure 13 illustrates some as applied to the Geneva font. Most combinations usually look good only for large font sizes. •••Refer to Figure 13.••• Figure 13–Stylistic Variations If you specify bold, each character is repeatedly drawn one bit to the right an appropriate number of times for extra thickness. Italic adds an italic slant to the characters. Character bits above the base line are skewed right; bits below the base line are skewed left. Underline draws a line below the base line of the characters. If part of a character descends below the base line (as “y” in Figure 13), the underline isn’t drawn through the pixel on either side of the descending part. Outline makes a hollow, outlined character rather than a solid one. Shadow also makes an outlined character, but the outline is thickened below and to the right of the character to achieve the effect of a shadow. If you specify bold along with outline or shadow, the hollow part of the character is widened. Condense and extend affect the horizontal distance between all characters, including spaces. Condense decreases the distance between characters and extend increases it, by an amount that the Font Manager determines is appropriate. The txMode field controls the way characters are placed in the bit image. It functions much like a pnMode: When a character is drawn, QuickDraw determines which bits in the bit image will be affected, does a bit-by-bit comparison based on the mode, and stores the resulting bits into the bit image. These modes are described under “Transfer Modes” in the section “General Discussion of Drawing”. Only three of them—srcOr, srcXor, and srcBic—should be used for drawing text. Note: If you use scrCopy, some extra blank space will be appended at the end of the text. The txSize field specifies the font size in points (where “point” is a typographical term meaning approximately 1/72 inch). Any size from 1 to 127 points may be specified. If the Font Manager doesn’t have the font in a specified size, it will scale a size it does have as necessary to produce the size desired. A value of 0 in this field represents the system font size (12 points). Finally, the spExtra field is useful when a line of characters is to be drawn justified such that it’s aligned with both a left and a right margin (sometimes called “full justification”). SpExtra contains a fixed-point number equal to the average number of pixels by which each space character should be widened to fill out the line. The Fixed data type is described in the Macintosh Memory Management: An Introduction chapter. _______________________________________________________________________________ »COORDINATES IN GRAFPORTS _______________________________________________________________________________ Each grafPort has its own local coordinate system. All fields in the grafPort are expressed in these coordinates, and all calculations and actions performed in QuickDraw use the local coordinate system of the currently selected port. Two things are important to remember: • Each grafPort maps a portion of the coordinate plane into a similarly- sized portion of a bit image. • The portBits.bounds rectangle defines the local coordinates for a grafPort. The top left corner of portBits.bounds is always aligned around the first bit in the bit image; the coordinates of that corner “anchor” a point on the grid to that bit in the bit image. This forms a common reference point for multiple grafPorts that use the same bit image (such as the screen); given a portBits.bounds rectangle for each port, you know that their top left corners coincide. The relationship between the portBits.bounds and portRect rectangles is very important: The portBits.bounds rectangle establishes a coordinate system for the port, and the portRect rectangle indicates the section of the coordinate plane (and thus the bit image) that will be used for drawing. The portRect usually falls inside the portBits.bounds rectangle, but it’s not required to do so. When a new grafPort is created, its bit map is set to point to the entire screen, and both the portBits.bounds and the portRect are set to rectangles enclosing the screen. The point (0,0) corresponds to the screen’s top left corner. You can redefine the local coordinates of the top left corner of the grafPort’s portRect, using the SetOrigin procedure. This offsets the coordinates of the grafPort’s portBits.bounds rectangle, recalculating the coordinates of all points in the grafPort to be relative to the new corner coordinates. For example, consider these procedure calls: SetPort(gamePort); SetOrigin(90,80) The call to SetPort sets the current grafPort to gamePort; the call to SetOrigin changes the local coordinates of the top left corner of that port’s portRect to (90,80) (see Figure 14). •••Refer to Figure 14.••• Figure 14–Changing Local Coordinates This offsets the coordinates of the following elements: gamePort^.portBits.bounds gamePort^.portRect gamePort^.visRgn These three elements are always kept “in sync”. Notice that when the local coordinates of a grafPort are offset, the grafPort’s clipRgn and pen location are not offset. A good way to think of it is that the port’s structure “sticks” to the screen, while the document in the grafPort (along with the pen and clipRgn) “sticks” to the coordinate system. For example, in Figure 14, before SetOrigin, the visRgn and clipRgn are the same as the portRect. After the SetOrigin call, the locations of portBits.bounds, portRect, and visRgn do not change on the screen; their coordinates are simply offset. As always, the top left corner of portBits.bounds remains “anchored” around the first bit in the bit image (the first pixel on the screen); the image on the screen doesn’t move as a result of SetOrigin. However, the pen location and clipRgn do move on the screen; the top left corner of the clipRgn is still (100,100), but this location has moved down and to the right, and the pen has similarly moved. If you’re moving, comparing, or otherwise dealing with mathematical items in different grafPorts (for example, finding the intersection of two regions in two different grafPorts), you must adjust to a common coordinate system before you perform the operation. A QuickDraw procedure, LocalToGlobal, lets you convert a point’s local coordinates to a global coordinate system where the top left corner of the bit image is (0,0); by converting the various local coordinates to global coordinates, you can compare and mix them with confidence. For more information, see the description of LocaltoGlobal under “Calculations with Points” in the “QuickDraw Routines” section. æKY ResumeProcPtr æFc Dialogs.h æT typedef æD typedef pascal void (*ResumeProcPtr)(void); æC æKY SoundProcPtr æFc Dialogs.h æT typedef æD typedef pascal void (*SoundProcPtr)(void); æC æKY DialogRecord DialogPeek æFc Dialogs.h æT struct æD struct DialogRecord { WindowRecord window; Handle items; TEHandle textH; short editField; short editOpen; short aDefItem; }; typedef struct DialogRecord DialogRecord; typedef DialogRecord *DialogPeek; æC »The DialogRecord Data Type For those who want to know more about the data structure of a dialog record, the exact structure is given here. TYPE DialogRecord = RECORD window: WindowRecord; {dialog window} items: Handle; {item list} textH: TEHandle; {current editText item} editField: INTEGER; {editText item number minus 1} editOpen: INTEGER; {used internally} aDefItem: INTEGER {default button item number} END; The window field contains the window record for the dialog window. The items field contains a handle to the item list used for the dialog. (Remember that after reading an item list from a resource file, the Dialog Manager makes a copy of it and uses that copy.) Note: To get or change information about an item in a dialog, you pass the dialog pointer and the item number to a Dialog Manager procedure. You’ll never access information directly through the handle to the item list. The Dialog Manager uses the next three fields when there are one or more editText items in the dialog. If there’s more than one such item, these fields apply to the one that currently is selected or displays the insertion point. The textH field contains the handle to the edit record used by TextEdit. EditField is 1 less than the item number of the current editText item, or –1 if there’s no editText item in the dialog. The editOpen field is used internally by the Dialog Manager. Note: Actually, a single edit record is shared by all editText items; any changes you make to it will apply to all such items. See the TextEdit chapter for details about what kinds of changes you can make. The aDefItem field is used for modal dialogs and alerts, which are treated internally as special modal dialogs. It contains the item number of the default button. The default button for a modal dialog is the first item in the item list, so this field contains 1 for modal dialogs. The default button for an alert is specified in the alert template; see the following section for more information. æKY DialogTemplate DialogTPtr DialogTHndl æFc Dialogs.h æT struct æD struct DialogTemplate { Rect boundsRect; short procID; Boolean visible; Boolean filler1; Boolean goAwayFlag; Boolean filler2; long refCon; short itemsID; Str255 title; }; typedef struct DialogTemplate DialogTemplate; typedef DialogTemplate *DialogTPtr, **DialogTHndl; æC »Dialog Templates in Memory The data structure of a dialog template is as follows: TYPE DialogTemplate = RECORD boundsRect: Rect; {becomes window's portRect} procID: INTEGER; {window definiton ID} visible: BOOLEAN; {TRUE if visible} filler1: BOOLEAN; {not used} goAwayFlag: BOOLEAN; {TRUE if has go-away region} filler2: BOOLEAN; {not used} refCon: LONGINT; {window's reference value} itemsID: INTEGER; {resource ID of item list} title: Str255 {window's title} END; The filler1 and filler2 fields are there because for historical reasons the goAwayFlag and refCon fields have to begin on a word boundary. The itemsID field contains the resource ID of the dialog’s item list. The other fields are the same as the parameters of the same name in the NewDialog function; they provide information about the dialog window. You access the dialog template by converting the handle returned by the Resource Manager to a template handle: TYPE DialogTHndl = ^DialogTPtr; DialogTPtr = ^DialogTemplate; æKY AlertTemplate AlertTPtr AlertTHndl æFc Dialogs.h æT struct æD struct AlertTemplate { Rect boundsRect; short itemsID; StageList stages; }; typedef struct AlertTemplate AlertTemplate; typedef AlertTemplate *AlertTPtr, **AlertTHndl; æC »Alert Templates in Memory The data structure of an alert template is as follows: TYPE AlertTemplate = RECORD boundsRect: Rect; {becomes window's portRect} itemsID: INTEGER; {resource ID of item list} stages: StageList {alert stage information} END; BoundsRect is the rectangle that becomes the portRect of the window's grafPort. The itemsID field contains the resource ID of the item list for the alert. The information in the stages field determines exactly what should happen at each stage of the alert. It's packed into a word that has the following structure: TYPE StageList = PACKED RECORD boldItm4: 0..1; {default button item number minus 1} boxDrwn4: BOOLEAN; {TRUE if alert box to be drawn} sound4: 0..3 {sound number} boldItm3: 0..1; boxDrwn3: BOOLEAN; sound3: 0..3 boldItm2: 0..1; boxDrwn2: BOOLEAN; sound2: 0..3 boldItm1: 0..1; boxDrwn1: BOOLEAN; sound1: 0..3 END; Notice that the information is stored in reverse order—for the fourth stage first, and for the first stage last. The boldItm field indicates which button should be the default button (and therefore boldly outlined in the alert box). If the first two items in the alert’s item list are the OK button and the Cancel button, respectively, 0 will refer to the OK button and 1 to the Cancel button. The reason for this is that the value of boldItm plus 1 is interpreted as an item number, and normally items 1 and 2 are the OK and Cancel buttons, respectively. Whatever the item having the corresponding item number happens to be, a bold rounded-corner rectangle will be drawn outside its display rectangle. Note: When deciding where to place items in an alert box, be sure to allow room for any bold outlines that may be drawn. The boxDrwn field is TRUE if the alert box is to be drawn. The sound field specifies which sound should be emitted at this stage of the alert, with a number from 0 to 3 that’s passed to the current sound procedure. You can call ErrorSound to specify your own sound procedure; if you don’t, the standard sound procedure will be used (as described earlier in the “Alerts” section). You access the alert template by converting the handle returned by the Resource Manager to a template handle: TYPE AlertTHndl = ^AlertTPtr; AlertTPtr = ^AlertTemplate; Assembly-language note: Rather than offsets into the fields of the StageList data structure, there are masks for accessing the information stored for an alert stage in a stages word; they’re listed in the summary at the end of this chapter. æKY InitDialogs æFc Dialogs.h æT Function æTN A97B æD pascal void InitDialogs(ResumeProcPtr resumeProc) = 0xA97B; æDT InitDialogs((ResumeProcPtr) resumeProc); æRI I-411, P-107, 112, 174 æC Call InitDialogs once before all other Dialog Manager routines, to initialize the Dialog Manager. InitDialogs does the following initialization: • It saves the pointer passed in resumeProc, if any, for access by the System Error Handler in case a fatal system error occurs. ResumeProc can be a pointer to a resume procedure, as described in the System Error Handler chapter, or NIL if no such procedure is desired. Assembly-language note: InitDialogs stores the address of the resume procedure in a global variable named ResumeProc. • It installs the standard sound procedure. • It passes empty strings to ParamText. æKY ErrorSound æFc Dialogs.h æT Function æTN A98C æD pascal void ErrorSound(SoundProcPtr soundProc) = 0xA98C; æDT ErrorSound((SoundProcPtr) soundProc); æRI I-411 æC ErrorSound sets the sound procedure for alerts to the procedure pointed to by soundProc; if you don’t call ErrorSound, the Dialog Manager uses the standard sound procedure. (For details, see the “Alerts” section.) If you pass NIL for soundProc, there will be no sound (or menu bar blinking) at all. Assembly-language note: The address of the sound procedure being used is stored in the global variable DABeeper. æKY NewDialog æFc Dialogs.h æT Function æTN A97D æD pascal DialogPtr NewDialog(Ptr wStorage,const Rect *boundsRect,const Str255 title, Boolean visible,short procID,WindowPtr behind,Boolean goAwayFlag,long refCon, Handle itmLstHndl) = 0xA97D; æDT DialogPtr myVariable = NewDialog((Ptr) wStorage,(const Rect *) boundsRect,(const Str255) title,() Boolean visible,(short) procID,(WindowPtr) behind,(Boolean) goAwayFlag,(long) refCon,() Handle itmLstHndl); æMM æRI I-412, P-107, 177 æC NewDialog creates a dialog as specified by its parameters and returns a pointer to the new dialog. The first eight parameters (dStorage through refCon) are passed to the Window Manager function NewWindow, which creates the dialog window; the meanings of these parameters are summarized below. The items parameter is a handle to the dialog’s item list. You can get the items handle by calling the Resource Manager to read the item list from the resource file into memory. Note: Advanced programmers can create their own item lists in memory rather than have them read from a resource file. The exact format is given later under “Formats of Resources for Dialogs and Alerts”. DStorage is analogous to the wStorage parameter of NewWindow; it’s a pointer to the storage to use for the dialog record. If you pass NIL for dStorage, the dialog record will be allocated in the heap (which, in the case of modeless dialogs, may cause the heap to become fragmented). BoundsRect, a rectangle given in global coordinates, determines the dialog window’s size and location. It becomes the portRect of the window’s grafPort. Remember that the top coordinate of this rectangle should be at least 25 points below the top of the screen for a modal dialog, to allow for the menu bar and the border around the portRect, and at least 40 points below the top of the screen for a modeless dialog, to allow for the menu bar and the window’s title bar. Title is the title of a modeless dialog box; pass the empty string for modal dialogs. If the visible parameter is TRUE, the dialog window is drawn on the screen. If it’s FALSE, the window is initially invisible and may later be shown with a call to the Window Manager procedure ShowWindow. Note: NewDialog generates an update event for the entire window contents, so the items aren’t drawn immediately, with the exception of controls. The Dialog Manager calls the Control Manager to draw controls, and the Control Manager draws them immediately rather than via the standard update mechanism. Because of this, the Dialog Manager calls the Window Manager procedure ValidRect for the enclosing rectangle of each control, so the controls won’t be drawn twice. If you find that the other items aren’t being drawn soon enough after the controls, try making the window invisible initially and then calling ShowWindow to show it. ProcID is the window definition ID, which leads to the window definition function for this type of window. The window definition IDs for the standard types of dialog window are dBoxProc for the modal type and documentProc for the modeless type. The behind parameter specifies the window behind which the dialog window is to be placed on the desktop. Pass POINTER(–1) to bring up the dialog window in front of all other windows. GoAwayFlag applies to modeless dialog boxes; if it’s TRUE, the dialog window has a close box in its title bar when the window is active. RefCon is the dialog window’s reference value, which the application may store into and access for any purpose. NewDialog sets the font of the dialog window’s grafPort to the system font or, if you previously called SetDAFont, to the specified font. It also sets the window class in the window record to dialogKind. æKY newdialog æFc Dialogs.h æT Function æTN A97D æD DialogPtr newdialog(Ptr wStorage,const Rect *boundsRect,char *title,Boolean visible, short procID,WindowPtr behind,Boolean goAwayFlag,long refCon,Handle itmLstHndl); æDT DialogPtr myVariable = newdialog((Ptr) wStorage,(const Rect *) boundsRect,(char *) title,(Boolean) visible,() short procID,(WindowPtr) behind,(Boolean) goAwayFlag,(long) refCon,(Handle) itmLstHndl); æMM æRI I-412, P-107, 177 æC NewDialog creates a dialog as specified by its parameters and returns a pointer to the new dialog. The first eight parameters (dStorage through refCon) are passed to the Window Manager function NewWindow, which creates the dialog window; the meanings of these parameters are summarized below. The items parameter is a handle to the dialog’s item list. You can get the items handle by calling the Resource Manager to read the item list from the resource file into memory. Note: Advanced programmers can create their own item lists in memory rather than have them read from a resource file. The exact format is given later under “Formats of Resources for Dialogs and Alerts”. DStorage is analogous to the wStorage parameter of NewWindow; it’s a pointer to the storage to use for the dialog record. If you pass NIL for dStorage, the dialog record will be allocated in the heap (which, in the case of modeless dialogs, may cause the heap to become fragmented). BoundsRect, a rectangle given in global coordinates, determines the dialog window’s size and location. It becomes the portRect of the window’s grafPort. Remember that the top coordinate of this rectangle should be at least 25 points below the top of the screen for a modal dialog, to allow for the menu bar and the border around the portRect, and at least 40 points below the top of the screen for a modeless dialog, to allow for the menu bar and the window’s title bar. Title is the title of a modeless dialog box; pass the empty string for modal dialogs. If the visible parameter is TRUE, the dialog window is drawn on the screen. If it’s FALSE, the window is initially invisible and may later be shown with a call to the Window Manager procedure ShowWindow. Note: NewDialog generates an update event for the entire window contents, so the items aren’t drawn immediately, with the exception of controls. The Dialog Manager calls the Control Manager to draw controls, and the Control Manager draws them immediately rather than via the standard update mechanism. Because of this, the Dialog Manager calls the Window Manager procedure ValidRect for the enclosing rectangle of each control, so the controls won’t be drawn twice. If you find that the other items aren’t being drawn soon enough after the controls, try making the window invisible initially and then calling ShowWindow to show it. ProcID is the window definition ID, which leads to the window definition function for this type of window. The window definition IDs for the standard types of dialog window are dBoxProc for the modal type and documentProc for the modeless type. The behind parameter specifies the window behind which the dialog window is to be placed on the desktop. Pass POINTER(–1) to bring up the dialog window in front of all other windows. GoAwayFlag applies to modeless dialog boxes; if it’s TRUE, the dialog window has a close box in its title bar when the window is active. RefCon is the dialog window’s reference value, which the application may store into and access for any purpose. NewDialog sets the font of the dialog window’s grafPort to the system font or, if you previously called SetDAFont, to the specified font. It also sets the window class in the window record to dialogKind. æKY GetNewDialog æFc Dialogs.h æT Function æTN A97C æD pascal DialogPtr GetNewDialog(short dialogID,Ptr dStorage,WindowPtr behind) = 0xA97C; æDT DialogPtr myVariable = GetNewDialog((short) dialogID,(Ptr) dStorage,(WindowPtr) behind); æMM æRT 4,34 æRI I-413, V-284, N4-1, P-107, 172 æC Like NewDialog (above), GetNewDialog creates a dialog as specified by its parameters and returns a pointer to the new dialog. Instead of having the parameters boundsRect, title, visible, procID, goAwayFlag, and refCon, GetNewDialog has a single dialogID parameter, where dialogID is the resource ID of a dialog template that supplies the same information as those parameters. The dialog template also contains the resource ID of the dialog’s item list. After calling the Resource Manager to read the item list into memory (if it’s not already in memory), GetNewDialog makes a copy of the item list and uses that copy; thus you may have multiple independent dialogs whose items have the same types, locations, and initial contents. The dStorage and behind parameters of GetNewDialog have the same meaning as in NewDialog. Warning: If either the dialog template resource or the item list resource can’t be read, the function result is undefined. Note: GetNewDialog doesn’t release the memory occupied by the resources. The GetNewDialog routine will attempt to load a 'dctb' resource and returns a pointer to a color grafPort if the resource exists. If no 'dctb' resource is present, GetNewDialog returns a pointer to an old grafPort. The dialog color table is copied before it is passed to SetWinSize unless its ctSize field is equal to –1, indicating that the default window colors are to be used instead. The copy is made so that the color table resource can be purged without affecting the dialog. The color dialog item list resource is duplicated as well, so it can be purgeable. æKY CloseDialog æFc Dialogs.h æT Function æTN A982 æD pascal void CloseDialog(DialogPtr theDialog) = 0xA982; æDT CloseDialog((DialogPtr) theDialog); æMM æRI I-413, P-107, 167 æC CloseDialog removes theDialog’s window from the screen and deletes it from the window list, just as when the Window Manager procedure CloseWindow is called. It releases the memory occupied by the following: • The data structures associated with the dialog window (such as the window’s structure, content, and update regions). • All the items in the dialog (except for pictures and icons, which might be shared resources), and any data structures associated with them. For example, it would dispose of the region occupied by the thumb of a scroll bar, or a similar region for some other control in the dialog. CloseDialog does not dispose of the dialog record or the item list. Figure 10 illustrates the effect of CloseDialog (and DisposDialog, described below). •••Refer to Figure 10.••• Figure 10–CloseDialog and DisposDialog Call CloseDialog when you’re done with a dialog if you supplied NewDialog or GetNewDialog with a pointer to the dialog storage (in the dStorage parameter) when you created the dialog. Note: Even if you didn’t supply a pointer to the dialog storage, you may want to call CloseDialog if you created the dialog with NewDialog. You would call CloseDialog if you wanted to keep the item list around (since, unlike GetNewDialog, NewDialog does not use a copy of the item list). æKY DisposDialog æFc Dialogs.h æT Function æTN A983 æD pascal void DisposDialog(DialogPtr theDialog) = 0xA983; æDT DisposDialog((DialogPtr) theDialog); æRI I-415 æC DisposDialog calls CloseDialog (above) and then releases the memory occupied by the dialog’s item list and dialog record. Call DisposDialog when you’re done with a dialog if you let the dialog record be allocated in the heap when you created the dialog (by passing NIL as the dStorage parameter to NewDialog or GetNewDialog). æKY CouldDialog æFc Dialogs.h æT Function æTN A979 æD pascal void CouldDialog(short dialogID) = 0xA979; æDT CouldDialog((short) dialogID); æMM æRI I-415, V-284 æC CouldDialog makes the dialog template having the given resource ID unpurgeable (reading it into memory if it’s not already there). It does the same for the dialog window’s definition function, the dialog’s item list resource, and any items defined as resources. This is useful if the dialog box may come up when the resource file isn’t accessible, such as during a disk copy. Warning: CouldDialog assumes your dialogs use the system font; if you’ve changed the font with SetDAFont, calling CouldDialog doesn’t make the font unpurgeable. The CouldDialog procedure makes the dialog color table template unpurgeable (reading it into memory if it isn’t already there), if it exists. It does the same for the dialog’s color item list, if it has one. Warning: CouldDialog doesn’t load or make 'FONT' or 'FOND' resources indicated in the color item list unpurgeable. æKY FreeDialog æFc Dialogs.h æT Function æTN A97A æD pascal void FreeDialog(short dialogID) = 0xA97A; æDT FreeDialog((short) dialogID); æMM æRI I-415, V-284 æC Given the resource ID of a dialog template previously specified in a call to CouldDialog, FreeDialog undoes the effect of CouldDialog (by making the resources purgeable). It should be called when there’s no longer a need to keep the resources in memory. Given the resource ID of a dialog template previously specified in a call to CouldDialog, the FreeDialog routine undoes the effect of CouldDialog, by restoring the original purge state of the color table and color item list resources. æKY ParamText æFc Dialogs.h æT Function æTN A98B æD pascal void ParamText(const Str255 param0,const Str255 param1,const Str255 param2, const Str255 param3) = 0xA98B; æDT ParamText((const Str255) param0,(const Str255) param1,(const Str255) param2,( const) Str255 param3); æMM æRI I-421 æC ParamText provides a means of substituting text in statText items: param0 through param3 will replace the special strings '^0' through '^3' in all statText items in all subsequent dialog or alert boxes. Pass empty strings for parameters not used. Assembly-language note: Assembly-language programmers may pass NIL for parameters not used or for strings that are not to be changed. For example, if the text is defined as 'Cannot open document ^0' and docName is a string variable containing a document name that the user typed, you can call ParamText(docName,' ',' ',' ') Note: All strings that may need to be translated to other languages should be stored in resource files. Assembly-language note: The Dialog Manager stores handles to the four ParamText parameters in a global array named DAStrings. æKY ModalDialog æFc Dialogs.h æT Function æTN A991 æD pascal void ModalDialog(ModalFilterProcPtr filterProc,short *itemHit) = 0xA991; æDT ModalDialog((ModalFilterProcPtr) filterProc,(short *) itemHit); æMM æRT 34, 203 æRI I-415, N34-2, 3, P-108, 176 æC Call ModalDialog after creating a modal dialog and bringing up its window in the frontmost plane. ModalDialog repeatedly gets and handles events in the dialog’s window; after handling an event involving an enabled dialog item, it returns with the item number in itemHit. Normally you’ll then do whatever is appropriate as a response to an event in that item. ModalDialog gets each event by calling the Toolbox Event Manager function GetNextEvent. If the event is a mouse-down event outside the content region of the dialog window, ModalDialog emits sound number 1 (which should be a single beep) and gets the next event; otherwise, it filters and handles the event as described below. Note: Once before getting each event, ModalDialog calls SystemTask, a Desk Manager procedure that must be called regularly so that desk accessories will work properly. The filterProc parameter determines how events are filtered. If it’s NIL, the standard filterProc function is executed; this causes ModalDialog to return 1 in itemHit if the Return key or Enter key is pressed. If filterProc isn’t NIL, ModalDialog filters events by executing the function it points to. Your filterProc function should have three parameters and return a Boolean value. For example, this is how it would be declared if it were named MyFilter: FUNCTION MyFilter (theDialog: DialogPtr; VAR theEvent: EventRecord; VAR itemHit: INTEGER) : BOOLEAN; A function result of FALSE tells ModalDialog to go ahead and handle the event, which either can be sent through unchanged or can be changed to simulate a different event. A function result of TRUE tells ModalDialog to return immediately rather than handle the event; in this case, the filterProc function sets itemHit to the item number that ModalDialog should return. Note: If you want it to be consistent with the standard filterProc function, your function should at least check whether the Return key or Enter key was pressed and, if so, return 1 in itemHit and a function result of TRUE. You can use the filterProc function, for example, to treat a typed character in a special way (such as ignore it, or make it have the same effect as another character or as clicking a button); in this case, the function would test for a key-down event with that character. As another example, suppose the dialog box contains a userItem whose procedure draws a clock with the current time displayed. The filterProc function can call that procedure and return FALSE without altering the current event. Note: ModalDialog calls GetNextEvent with a mask that excludes disk-inserted events. To receive disk-inserted events, your filterProc function can call GetNextEvent (or EventAvail) with a mask that accepts only that type of event. ModalDialog handles the events for which the filterProc function returns FALSE as follows: • In response to an activate or update event for the dialog window, ModalDialog activates or updates the window. • If the mouse button is pressed in an editText item, ModalDialog responds to the mouse activity as appropriate (displaying an insertion point or selecting text). If a key-down event occurs and there’s an editText item, text entry and editing are handled in the standard way for such items (except that if the Command key is down, ModalDialog responds as though it’s not). In either case, ModalDialog returns if the editText item is enabled or does nothing if it’s disabled. If a key-down event occurs when there’s no editText item, ModalDialog does nothing. • If the mouse button is pressed in a control, ModalDialog calls the Control Manager function TrackControl. If the mouse button is released inside the control and the control is enabled, ModalDialog returns; otherwise, it does nothing. • If the mouse button is pressed in any other enabled item in the dialog box, ModalDialog returns. If the mouse button is pressed in any other disabled item or in no item, or if any other event occurs, ModalDialog does nothing. æKY IsDialogEvent æFc Dialogs.h æT Function æTN A97F æD pascal Boolean IsDialogEvent(const EventRecord *theEvent) = 0xA97F; æDT Boolean myVariable = IsDialogEvent((const EventRecord *) theEvent); æRI I-416, N5-1, P-108, 175 æC If your application includes any modeless dialogs, call IsDialogEvent after calling the Toolbox Event Manager function GetNextEvent. Warning: If your modeless dialog contains any editText items, you must call IsDialogEvent (and then DialogSelect) even if GetNextEvent returns FALSE; otherwise your dialog won’t receive null events and the caret won’t blink. Pass the current event in theEvent. IsDialogEvent determines whether theEvent needs to be handled as part of a dialog. If theEvent is an activate or update event for a dialog window, a mouse-down event in the content region of an active dialog window, or any other type of event when a dialog window is active, IsDialogEvent returns TRUE; otherwise, it returns FALSE. When FALSE is returned, just handle the event yourself like any other event that’s not dialog-related. When TRUE is returned, you’ll generally end up passing the event to DialogSelect for it to handle (as described below), but first you should do some additional checking: • DialogSelect doesn’t handle keyboard equivalents of commands. Check whether the event is a key-down event with the Command key held down and, if so, carry out the command if it’s one that applies when a dialog window is active. (If the command doesn’t so apply, do nothing.) • In special cases, you may want to bypass DialogSelect or do some preprocessing before calling it. If so, check for those events and respond accordingly. You would need to do this, for example, if the dialog is to respond to disk-inserted events. For cases other than these, pass the event to DialogSelect for it to handle. æKY DialogSelect æFc Dialogs.h æT Function æTN A980 æD pascal Boolean DialogSelect(const EventRecord *theEvent,DialogPtr *theDialog, short *itemHit) = 0xA980; æDT Boolean myVariable = DialogSelect((const EventRecord *) theEvent,(DialogPtr *) theDialog,( short) * itemHit); æMM æRT 34 æRI I-417, N34-3, P-108, 168 æC You’ll normally call DialogSelect when IsDialogEvent returns TRUE, passing in theEvent an event that needs to be handled as part of a modeless dialog. DialogSelect handles the event as described below. If the event involves an enabled dialog item, DialogSelect returns a function result of TRUE with the dialog pointer in theDialog and the item number in itemHit; otherwise, it returns FALSE with theDialog and itemHit undefined. Normally when DialogSelect returns TRUE, you’ll do whatever is appropriate as a response to the event, and when it returns FALSE you’ll do nothing. If the event is an activate or update event for a dialog window, DialogSelect activates or updates the window and returns FALSE. If the event is a mouse-down event in an editText item, DialogSelect responds as appropriate (displaying a caret at the insertion point or selecting text). If it’s a key-down or auto-key event and there’s an editText item, text entry and editing are handled in the standard way. In either case, DialogSelect returns TRUE if the editText item is enabled or FALSE if it’s disabled. If a key-down or auto-key event is passed when there’s no editText item, DialogSelect returns FALSE. Note: For a keyboard event, DialogSelect doesn’t check to see whether the Command key is held down; to handle keyboard equivalents of commands, you have to check for them before calling DialogSelect. Similarly, to treat a typed character in a special way (such as ignore it, or make it have the same effect as another character or as clicking a button), you need to check for a key-down event with that character before calling DialogSelect. If the event is a mouse-down event in a control, DialogSelect calls the Control Manager function TrackControl. If the mouse button is released inside the control and the control is enabled, DialogSelect returns TRUE; otherwise, it returns FALSE. If the event is a mouse-down event in any other enabled item, DialogSelect returns TRUE. If it’s a mouse-down event in any other disabled item or in no item, or if it’s any other event, DialogSelect returns FALSE. Note: If the event isn’t one that DialogSelect specifically checks for (if it’s a null event, for example), and there’s an editText item in the dialog, DialogSelect calls the TextEdit procedure TEIdle to make the caret blink. æKY DrawDialog æFc Dialogs.h æT Function æTN A981 æD pascal void DrawDialog(DialogPtr theDialog) = 0xA981; æDT DrawDialog((DialogPtr) theDialog); æMM æRI I-418 æC DrawDialog draws the contents of the given dialog box. Since DialogSelect and ModalDialog handle dialog window updating, this procedure is useful only in unusual situations. You would call it, for example, to display a dialog box that doesn’t require any response but merely tells the user what’s going on during a time-consuming process. æKY UpdtDialog æFc Dialogs.h æT Function æTN A978 æD pascal void UpdtDialog(DialogPtr theDialog,RgnHandle updateRgn) = 0xA978; æDT UpdtDialog((DialogPtr) theDialog,(RgnHandle) updateRgn); æMM æRI IV-60 æC UpdtDialog is a faster version of the DrawDialog procedure. Instead of drawing the entire contents of the given dialog box, UpdtDialog draws only the items that are in a specified update region. UpdtDialog is called in response to an update event, and is usually bracketed by calls to the Window Manager procedures BeginUpdate and EndUpdate. UpdateRgn should be set to the visRgn of theWindow’s port. (For more details, see the BeginUpdate procedure in the Window Manager chapter.) æKY Alert æFc Dialogs.h æT Function æTN A985 æD pascal short Alert(short alertID,ModalFilterProcPtr filterProc) = 0xA985; æDT short myVariable = Alert((short) alertID,(ModalFilterProcPtr) filterProc); æMM æRI I-418, V-284 æC This function invokes the alert defined by the alert template that has the given resource ID. It calls the current sound procedure, if any, passing it the sound number specified in the alert template for this stage of the alert. If no alert box is to be drawn at this stage, Alert returns a function result of –1; otherwise, it creates and displays the alert window for this alert and draws the alert box. Warning: If the alert template resource can’t be read, the function result is undefined. Note: Alert creates the alert window by calling NewDialog, and does the rest of its processing by calling ModalDialog. Alert repeatedly gets and handles events in the alert window until an enabled item is clicked, at which time it returns the item number. Normally you’ll then do whatever is appropriate in response to a click of that item. Alert gets each event by calling the Toolbox Event Manager function GetNextEvent. If the event is a mouse-down event outside the content region of the alert window, Alert emits sound number 1 (which should be a single beep) and gets the next event; otherwise, it filters and handles the event as described below. The filterProc parameter has the same meaning as in ModalDialog (see above). If it’s NIL, the standard filterProc function is executed, which makes the Return key or the Enter key have the same effect as clicking the default button. If you specify your own filterProc function and want to retain this feature, you must include it in your function. You can find out what the current default button is by looking at the aDefItem field of the dialog record for the alert (via the dialog pointer passed to the function). Alert handles the events for which the filterProc function returns FALSE as follows: • If the mouse button is pressed in a control, Alert calls the Control Manager procedure TrackControl. If the mouse button is released inside the control and the control is enabled, Alert returns; otherwise, it does nothing. • If the mouse button is pressed in any other enabled item, Alert simply returns. If it’s pressed in any other disabled item or in no item, or if any other event occurs, Alert does nothing. Before returning to the application with the item number, Alert removes the alert box from the screen. (It disposes of the alert window and its associated data structures, the item list, and the items.) Note: When an alert is removed, if it was overlapping the default button of a previous alert, that button’s bold outline won’t be redrawn. Note: The Alert function’s removal of the alert box would not be the desired result if the user clicked a check box or radio button; however, normally alerts contain only static text, icons, pictures, and buttons that are supposed to make the alert box go away. If your alert contains other items besides these, consider whether it might be more appropriate as a dialog. The Alert function looks for a resource of type 'actb' with the same ID as the alert. The alert color table is copied before it is passed to SetWinSize unless its ctSize field is equal to –1, indicating that the default window colors are to be used instead. The copy is made so that the color table resource can be purged without affecting the alert. The color dialog item list resource is duplicated as well, so it can be purgeable. æKY StopAlert æFc Dialogs.h æT Function æTN A986 æD pascal short StopAlert(short alertID,ModalFilterProcPtr filterProc) = 0xA986; æDT short myVariable = StopAlert((short) alertID,(ModalFilterProcPtr) filterProc); æMM æRI I-419, V-284, P-109, 182 æC StopAlert is the same as the Alert function (above) except that before drawing the items of the alert in the alert box, it draws the Stop icon in the top left corner of the box (within the rectangle (10,20)(42,52)). The Stop icon has the following resource ID: CONST stopIcon = 0; If the application’s resource file doesn’t include an icon with that ID number, the Dialog Manager uses the standard Stop icon in the system resource file (see Figure 11). The calls CautionAlert, StopAlert, and NoteAlert look for a resource of type 'actb' with the same ID as the alert. •••Refer to Figure 11.••• Figure 11–Standard Alert Icons æKY NoteAlert æFc Dialogs.h æT Function æTN A987 æD pascal short NoteAlert(short alertID,ModalFilterProcPtr filterProc) = 0xA987; æDT short myVariable = NoteAlert((short) alertID,(ModalFilterProcPtr) filterProc); æMM æRI I-420 æC NoteAlert is like StopAlert except that it draws the Note icon, which has the following resource ID: CONST noteIcon = 1; The calls CautionAlert, StopAlert, and NoteAlert look for a resource of type 'actb' with the same ID as the alert. æKY CautionAlert æFc Dialogs.h æT Function æTN A988 æD pascal short CautionAlert(short alertID,ModalFilterProcPtr filterProc) = 0xA988; æDT short myVariable = CautionAlert((short) alertID,(ModalFilterProcPtr) filterProc); æMM æRI I-420 æC CautionAlert is like StopAlert except that it draws the Caution icon, which has the following resource ID: CONST cautionIcon = 2; The calls CautionAlert, StopAlert, and NoteAlert look for a resource of type 'actb' with the same ID as the alert. æKY CouldAlert æFc Dialogs.h æT Function æTN A989 æD pascal void CouldAlert(short alertID) = 0xA989; æDT CouldAlert((short) alertID); æMM æRI I-420, V-285 æC CouldAlert makes the alert template having the given resource ID unpurgeable (reading it into memory if it’s not already there). It does the same for the alert window’s definition function, the alert’s item list resource, and any items defined as resources. This is useful if the alert may occur when the resource file isn’t accessible, such as during a disk copy. Warning: Like CouldDialog, CouldAlert assumes your alerts use the system font; if you’ve changed the font with SetDAFont, calling CouldAlert doesn’t make the font unpurgeable. The CouldAlert routine makes the alert color table template unpurgeable (reading it into memory if it isn’t already there), if it exists. It does the same for the alert’s color item list, if it has one. Warning: Like CouldDialog, CouldAlert doesn’t load or make 'FONT' or 'FOND' resources indicated in the color item list unpurgeable. æKY FreeAlert æFc Dialogs.h æT Function æTN A98A æD pascal void FreeAlert(short alertID) = 0xA98A; æDT FreeAlert((short) alertID); æMM æRI I-420, V-285 æC Given the resource ID of an alert template previously specified in a call to CouldAlert, FreeAlert undoes the effect of CouldAlert (by making the resources purgeable). It should be called when there’s no longer a need to keep the resources in memory. Given the resource ID of an alert template previously specified in a call to CouldAlert, the FreeAlert routine undoes the effect of CouldAlert, by restoring the original purge state of the color table and color item list resources. æKY GetDItem æFc Dialogs.h æT Function æTN A98D æD pascal void GetDItem(DialogPtr theDialog,short itemNo,short *itemType,Handle *item, Rect *box) = 0xA98D; æDT GetDItem((DialogPtr) theDialog,(short) itemNo,(short *) itemType,(Handle *) item,( Rect) * box); æMM æRI I-421 æC GetDItem returns in its VAR parameters the following information about the item numbered itemNo in the given dialog’s item list: In the itemType parameter, the item type; in the item parameter, a handle to the item (or, for item type userItem, the procedure pointer); and in the box parameter, the display rectangle for the item. Suppose, for example, that you want to change the title of a control in a dialog box. You can get the item handle with GetDItem, coerce it to type ControlHandle, and call the Control Manager procedure SetCTitle to change the title. Similarly, to move the control or change its size, you would call MoveControl or SizeControl. Note: To access the text of a statText or editText item, you can pass the handle returned by GetDItem to GetIText or SetIText (see below). æKY SetDItem æFc Dialogs.h æT Function æTN A98E æD pascal void SetDItem(DialogPtr theDialog,short itemNo,short itemType,Handle item, const Rect *box) = 0xA98E; æDT SetDItem((DialogPtr) theDialog,(short) itemNo,(short) itemType,(Handle) item,( const Rect) * box); æMM æRT 34 æRI I-421, N34-1 æC SetDItem sets the item numbered itemNo in the given dialog’s item list, as specified by the parameters (without drawing the item). The itemType parameter is the item type; the item parameter is a handle to the item (or, for item type userItem, the procedure pointer); and the box parameter is the display rectangle for the item. Consider, for example, how to install an item of type userItem in a dialog: In the item list in the resource file, define an item in which the type is set to userItem and the display rectangle to (0,0)(0,0). Specify that the dialog window be invisible (in either the dialog template or the NewDialog call). After creating the dialog, coerce the item’s procedure pointer to type Handle; then call SetDItem, passing that handle and the display rectangle for the item. Finally, call the Window Manager procedure ShowWindow to display the dialog window. Note: Do not use SetDItem to change the text of a statText or editText item or to change or move a control. See the description of GetDItem above for more information. æKY HideDItem æFc Dialogs.h æT Function æTN A827 æD pascal void HideDItem(DialogPtr theDialog,short itemNo) = 0xA827; æDT HideDItem((DialogPtr) theDialog,(short) itemNo); æMM æRI IV-59 æC HideDItem hides the item numbered itemNo in the given dialog’s item list by giving the item a display rectangle that’s off the screen. (Specifically, if the left coordinate of the item’s display rectangle is less than 8192, ShowDItem adds 16384 to both the left and right coordinates the rectangle.) If the item is already hidden (that is, if the left coordinate is greater than 8192), HideDItem does nothing. HideDItem calls the EraseRect procedure on the item’s enclosing rectangle and adds the rectangle that contained the item (not necessarily the item’s display rectangle) to the update region. If the specified item is an active editText item, the item is first deactivated (by calling TEDeactivate). Note: If you have items that are close to each other, be aware that the Dialog Manager draws outside of the enclosing rectangle by 3 pixels for editText items and by 4 pixels for a default button. An item that’s been hidden by HideDItem can be redisplayed by the ShowDItem procedure. Note: To create a hidden item in a dialog item list, simply add 16384 to the left and right coordinates of the display rectangle. æKY ShowDItem æFc Dialogs.h æT Function æTN A828 æD pascal void ShowDItem(DialogPtr theDialog,short itemNo) = 0xA828; æDT ShowDItem((DialogPtr) theDialog,(short) itemNo); æMM æRI IV-59 æC ShowDItem redisplays the item numbered itemNo, previously hidden by HideDItem, by giving the item the display rectangle it had prior to the HideDItem call. (Specifically, if the left coordinate of the item’s display rectangle is greater than 8192, ShowDItem subtracts 16384 from both the left and right coordinates of the rectangle.) If the item is already visible (that is, if the left coordinate is less than 8192), ShowDItem does nothing. ShowDItem adds the rectangle that contained the item (not necessarily the item’s display rectangle) to the update region so that it will be drawn. If the item becomes the only editText item, ShowDItem activates it (by calling TEActivate). æKY SelIText æFc Dialogs.h æT Function æTN A97E æD pascal void SelIText(DialogPtr theDialog,short itemNo,short strtSel,short endSel) = 0xA97E; æDT SelIText((DialogPtr) theDialog,(short) itemNo,(short) strtSel,(short) endSel); æMM æRI I-422, P-110 æC Given a pointer to a dialog and the item number of an editText item in the dialog box, SelIText does the following: • If the item contains text, SelIText sets the selection range to extend from character position strtSel up to but not including character position endSel. The selection range is inverted unless strtSel equals endSel, in which case a blinking vertical bar is displayed to indicate an insertion point at that position. • If the item doesn’t contain text, SelIText simply displays the insertion point. For example, if the user makes an unacceptable entry in the editText item, the application can put up an alert box reporting the problem and then select the entire text of the item so it can be replaced by a new entry. (Without this procedure, the user would have to select the item before making the new entry.) Note: You can select the entire texxt by specifying 0 for strtSel and 32767 for endSel. For details about selection range and character position, see the TextEdit chapter. æKY GetIText æFc Dialogs.h æT Function æTN A990 æD pascal void GetIText(Handle item,Str255 text) = 0xA990; æDT GetIText((Handle) item,(Str255) text); æRT 18 æRI I-422, N18-2 æC Given a handle to a statText or editText item in a dialog box, as returned by GetDItem, GetIText returns the text of the item in the text parameter. (If the user typed more than 255 characters in an editText item, GetIText returns only the first 255.) æKY SetIText æFc Dialogs.h æT Function æTN A98F æD pascal void SetIText(Handle item,const Str255 text) = 0xA98F; æDT SetIText((Handle) item,(const Str255) text); æMM æRI I-422 æC Given a handle to a statText or editText item in a dialog box, as returned by GetDItem, SetIText sets the text of the item to the specified text and draws the item. For example, suppose the exact content of a dialog’s text item cannot be determined until the application is running, but the display rectangle is defined in the resource file: Call GetDItem to get a handle to the item, and call SetIText with the desired text. æKY FindDItem æFc Dialogs.h æT Function æTN A984 æD pascal short FindDItem(DialogPtr theDialog,Point thePt) = 0xA984; æDT short myVariable = FindDItem((DialogPtr) theDialog,(Point) thePt); æMM æRT 112 æRI IV-60, N112 æC FindDItem returns the item number of the item containing the point specified, in local coordinates, by thePt. If the point doesn’t lie within the item’s rectangle, FindDItem returns –1. If there are overlapping items, it returns the item number of the first item in the list containing the point. FindDItem is useful for changing the cursor when it’s over a particular item. Note: FindDItem will return the item number of disabled items as well. æKY NewCDialog æFc Dialogs.h æT Function æTN AA4B æD pascal DialogPtr NewCDialog(Ptr dStorage,const Rect *boundsRect,const Str255 title, Boolean visible,short procID,WindowPtr behind,Boolean goAwayFlag,long refCon, Handle items) = 0xAA4B; æDT DialogPtr myVariable = NewCDialog((Ptr) dStorage,(const Rect *) boundsRect,(const Str255) title,() Boolean visible,(short) procID,(WindowPtr) behind,(Boolean) goAwayFlag,(long) refCon,() Handle items); æMM æRI V-283 æC A new Dialog Manager routine has been added to support color dialogs: NewCDialog. Its parameters are identical to NewDialog, except that a cGrafPort is allocated through a NewCWindow call instead of a call to NewWindow. NewCDialog creates a dialog box as specified by its parameters and returns a cDialogPtr to the new dialog. The first eight parameters (dStorage through refCon) are passed to the Window Manager function NewCWindow, which creates the dialog window. The items parameter is a handle to the dialog’s item list. You can get the items handle by calling the Resource Manager to read the item list from the resource file into memory. After calling NewCDialog, you can use SetWinColor to add a color table to the dialog. This creates an auxiliary window record (auxWinRec) for the dialog window. You can access this record with the GetAuxWin routine. The dialogCItem handle within the auxWinRec points to the dialog item color table. If the dialog’s content color isn’t white, it’s a good idea to call NewCDialog with the visible flag set to FALSE. After the color table and color item list are installed, use ShowWindow to display the dialog if the dialog is the frontmost window. If the dialog is not in front, use ShowHide to display the dialog. æKY newcdialog æFc Dialogs.h æT Function æD DialogPtr newcdialog(Ptr dStorage,const Rect *boundsRect,char *title,Boolean visible, short procID,WindowPtr behind,Boolean goAwayFlag,long refCon,Handle items); æDT DialogPtr myVariable = newcdialog((Ptr) dStorage,(const Rect *) boundsRect,(char *) title,(Boolean) visible,() short procID,(WindowPtr) behind,(Boolean) goAwayFlag,(long) refCon,(Handle) items); æRI V-283 æC A new Dialog Manager routine has been added to support color dialogs: NewCDialog. Its parameters are identical to NewDialog, except that a cGrafPort is allocated through a NewCWindow call instead of a call to NewWindow. NewCDialog creates a dialog box as specified by its parameters and returns a cDialogPtr to the new dialog. The first eight parameters (dStorage through refCon) are passed to the Window Manager function NewCWindow, which creates the dialog window. The items parameter is a handle to the dialog’s item list. You can get the items handle by calling the Resource Manager to read the item list from the resource file into memory. After calling NewCDialog, you can use SetWinColor to add a color table to the dialog. This creates an auxiliary window record (auxWinRec) for the dialog window. You can access this record with the GetAuxWin routine. The dialogCItem handle within the auxWinRec points to the dialog item color table. If the dialog’s content color isn’t white, it’s a good idea to call NewCDialog with the visible flag set to FALSE. After the color table and color item list are installed, use ShowWindow to display the dialog if the dialog is the frontmost window. If the dialog is not in front, use ShowHide to display the dialog. æKY GetAlrtStage æFc Dialogs.h æT Function æD pascal short GetAlrtStage(void) = {0x3EB8,0x0A9A}; æDT short myVariable = GetAlrtStage()(void); æRI I-422 æC GetAlrtStage returns the stage of the last occurrence of an alert, as a number from 0 to 3. Assembly-language note: Assembly-language programmers can get this number by accessing the global variable ACount. In addition, the global variable ANumber contains the resource ID of the alert template of the last alert that occurred. æKY ResetAlrtStage æFc Dialogs.h æT Function æD pascal void ResetAlrtStage(void) = {0x4278,0x0A9A}; æDT ResetAlrtStage()(void); æRI I-423 æC ResetAlrtStage resets the stage of the last occurrence of an alert so that the next occurrence of that same alert will be treated as its first stage. This is useful, for example, when you’ve used ParamText to change the text of an alert such that from the user’s point of view it’s a different alert. Assembly-language note: Assembly-language programmers can set the global variable ACount to –1 for the same effect. æKY DlgCut æFc Dialogs.h æT Function æD pascal void DlgCut(DialogPtr theDialog); æDT DlgCut((DialogPtr) theDialog); æRT 215 æRI I-418, P-110 æC [Not in ROM] DlgCut checks whether theDialog has any editText items and, if so, applies the TextEdit procedure TECut to the currently selected editText item. (If the dialog record’s editField is 0 or greater, DlgCut passes the contents of the textH field to TECut.) You can call DlgCut to handle the editing command Cut when a modeless dialog window is active. Assembly-language note: Assembly-language programmers can just read the dialog record’s fields and call TextEdit directly. æKY DlgPaste æFc Dialogs.h æT Function æD pascal void DlgPaste(DialogPtr theDialog); æDT DlgPaste((DialogPtr) theDialog); æMM æRT 215 æRI I-418, P-110 æC [Not in ROM] DlgPaste is the same as DlgCut (above) except that it calls TEPaste, for handling the Paste command. æKY DlgCopy æFc Dialogs.h æT Function æD pascal void DlgCopy(DialogPtr theDialog); æDT DlgCopy((DialogPtr) theDialog); æMM æRT 215 æRI I-418, P-110 æC [Not in ROM] DlgCopy is the same as DlgCut (above) except that it calls TECopy, for handling the Copy command. æKY DlgDelete æFc Dialogs.h æT Function æD pascal void DlgDelete(DialogPtr theDialog); æDT DlgDelete((DialogPtr) theDialog); æMM æRT 215 æRI I-418, P-110 æC [Not in ROM] DlgDelete is the same as DlgCut (above) except that it calls TEDelete, for handling the Clear command. æKY SetDAFont æFc Dialogs.h æT Function æD pascal void SetDAFont(short fontNum); æDT SetDAFont((short) fontNum); æRI I-412 æC For subsequently created dialogs and alerts, SetDAFont causes the font of the dialog or alert window’s grafPort to be set to the font having the specified font number. If you don’t call this procedure, the system font is used. SetDAFont affects statText and editText items but not titles of controls, which are always in the system font. Assembly-language note: Assembly-language programmers can simply set the global variable DlgFont to the desired font number. æKY paramtext æFc Dialogs.h æT Function æD void paramtext(char *param0,char *param1,char *param2,char *param3); æDT paramtext((char *) param0,(char *) param1,(char *) param2,(char *) param3); æMM æRI I-421 æC ParamText provides a means of substituting text in statText items: param0 through param3 will replace the special strings '^0' through '^3' in all statText items in all subsequent dialog or alert boxes. Pass empty strings for parameters not used. Assembly-language note: Assembly-language programmers may pass NIL for parameters not used or for strings that are not to be changed. For example, if the text is defined as 'Cannot open document ^0' and docName is a string variable containing a document name that the user typed, you can call ParamText(docName,' ',' ',' ') Note: All strings that may need to be translated to other languages should be stored in resource files. Assembly-language note: The Dialog Manager stores handles to the four ParamText parameters in a global array named DAStrings. æKY getitext æFc Dialogs.h æT Function æD void getitext(Handle item,char *text); æDT getitext((Handle) item,(char *) text); æRT 18 æRI I-422, N18-2 æC Given a handle to a statText or editText item in a dialog box, as returned by GetDItem, GetIText returns the text of the item in the text parameter. (If the user typed more than 255 characters in an editText item, GetIText returns only the first 255.) æKY setitext æFc Dialogs.h æT Function æD void setitext(Handle item,char *text); æDT setitext((Handle) item,(char *) text); æMM æRI I-422 æC Given a handle to a statText or editText item in a dialog box, as returned by GetDItem, SetIText sets the text of the item to the specified text and draws the item. For example, suppose the exact content of a dialog’s text item cannot be determined until the application is running, but the display rectangle is defined in the resource file: Call GetDItem to get a handle to the item, and call SetIText with the desired text. æKY findditem æFc Dialogs.h æT Function æD short findditem(DialogPtr theDialog,Point *thePt); æDT short myVariable = findditem((DialogPtr) theDialog,(Point *) thePt); æRI IV-60, N112 æC FindDItem returns the item number of the item containing the point specified, in local coordinates, by thePt. If the point doesn’t lie within the item’s rectangle, FindDItem returns –1. If there are overlapping items, it returns the item number of the first item in the list containing the point. FindDItem is useful for changing the cursor when it’s over a particular item. Note: FindDItem will return the item number of disabled items as well. æKY DisAsmLookup.h æKL Disassembler endOfModule InitLookup Lookup LookupTrapName ModifyOperand showMacsBugSymbol validMacsBugSymbol _A0_ _A1_ _A2_ _A3_ _A4_ _A5_ _A6_ _A7_ _ABS_ _PC_ _TRAP_ LookupRegs æKY Disassembler æFc DisAsmLookup.h æT Function æD pascal void Disassembler(long DstAdjust,short *BytesUsed,Ptr FirstByte, char *Opcode,char *Operand,char *Comment,Ptr LookUpProc); æDT Disassembler((long)DstAdjust,(short *)BytesUsed,(Ptr)FirstByte, (char *)Opcode,(char *)Operand,(char *)Comment,(Ptr)LookUpProc); æC /* Disassembler is a Pascal routine to be called to disassemble a sequence of bytes. All MC68xxx, MC68881, and MC68851 instructions are supported. The sequence of bytes to be disassembled are pointed to by FirstByte. BytesUsed bytes starting at FirstByte are consumed by the disassembly, and the Opcode, Operand, and Comment strings returned as NULL TERMINATED Pascal strings (for easier manipulation with C). The caller is then free to format or use the output strings any way appropriate to the application. Depending on the opcode and effective address(s) (EA's) to be disassembled, the Opcode, Operand, and Comment strings contain the following information: Case Opcode Operand Comment ======================================================================= Non PC-relative EA's op.sz EA's PC-relative EA's op.sz EA's ; address Toolbox traps DC.W $AXXX ; TB XXXX OS traps DC.W $AXXX ; OS XXXX Invalid bytes DC.W $XXXX ; ???? Invalid byte #immediate DC.W $XXXX,... ; op.sz #$??XX,EA ======================================================================= For valid disassembly of processor instructions the appropriate MC68XXX opcode mnemonic is generated for the Opcode string along with a size attribute when required. The source and destination EA's are generated as the Operand along with a possible comment. Comments start with a ';'. Traps use a DC.W assembler directive as the Opcode with the trap word as the Operand and a comment indicating whether the trap is a toolbox or OS trap and what the trap number is. As described later the caller can generate symbolic substitutions into EA's and provide names for traps. Invalid instructions cause the string 'DC.W' to be returned in the Opcode string. Operand is '$XXXX' (the invalid word) with a comment of '; ????'. BytesUsed is 2. This is similar to the trap call case except for the comment. A special case is made for immediate byte operands with a nonzero high order byte. For example, the bytes $020011FF, when actually executed, would be interpreted as ANDI.B $FF,D0. The processor will IGNORE the high order byte of the immediate data! Thus, the bytes may be considered as valid. Since the Disassembler has no way of knowing the context in which it is disassembling, it returns the Opcode as 'DC.W' as in the normal invalid case. However, the Operand string shows ALL the words disassembled separated with commas and places the possibly valid disassembly in the Operand's comment indicating the nonzero bytes. Thus for the example $020011FF bytes, the Opcode will be 'DC.W', the Operand will be '$0200,$11FF', and the Comment '; ANDI.B #$??FF,D0'. BytesUsed in this case would be 4. Note, the Operand EA's is syntatically similar to but NOT COMPATIBLE with the MPW assembler! This is because the Disassembler generates byte hex constants as "$XX" and word hex constants as "$XXXX". Negative values (e.g., $FF or $FFFF) produced by the Disassembler are treated as long word values by the MPW assembler. Thus it is assumed that Disassembler output will NOT be used as MPW assembler input. If that is the goal, then the caller must convert strings of the form $XX or $XXXX in the Operand string to their decimal equivalent. The routine ModifyOperand is provided in this unit to aid with the conversion process. Since a PC-relative comment is an address, the only address that the Disassembler knows about is the address of the code pointed to by FirstByte. Generally, that may be a buffer that has no relation to "reality", i.e., the actual code loaded into the buffer. Therefore, to allow the address comment to be mapped back to some actual address the caller may specify an adjustment factor, specified by DstAdjust that is ADDED to the value that normally would be placed in the comment. Operand effective address strings are generated as a function of the effective address mode and a special case is made for A-trap opcode strings. In places where a possible symbolic reference could be substituted for an address (or a portion of an address), the Disassembler can call a user specified routine to do the substitution (using th LookupProc parameter described later). The following table summarizes the generated effective addresses and where symbolic substitutions (S) can be made: Mode Generated Effective Address Effective Address with Substitution ======================================================================== 0 Dn Dn 1 An An 2 (An) (An) 3 (An)+ (An)+ 4 -(An) -(An) 5 ∂(An) S(An) or just S (if An=A5, ∂≥0) 6n ∂(An,Xn.Size*Scale) S(An,Xn.Size*Scale) 6n (BD,An,Xn.Size*Scale) (S,An,Xn.Size*Scale) 6n ([BD,An],Xm.Size*Scale,OD) ([S,An],Xm.Size*Scale,OD) 6n ([BD,An,Xn.Size*Scale],OD) ([S,An,Xn.Size*Scale],OD) 70 ∂ S 71 ∂ S 72 *±∂ S 73 *±∂(Xn.Size*Scale) S(Xn.Size*Scale) 73 (*±∂,Xn.Size*Scale) (S,Xn.Size*Scale) 73 ([*±∂],Xm.Size*Scale,OD) ([S],Xm.Size*Scale,OD) 73 ([*±∂,Xn.Size*Scale],OD) ([S,Xn.Size*Scale],OD) 74 #data #data ======================================================================== For A-traps, the substitution can be performed to substitute for the DC.W opcode string. If the substitution is made then the Disassembler will generate ,Sys and/or ,Immed flags as operands for Toolbox traps and ,AutoPop for OS traps when the bits in the trap word indicates these settings. | Generated | Substituted | Opcode Operand Comment | Opcode Operand Comment ======================================================================== Toolbox | DC.W $AXXX ; TB XXXX | S [,Sys][,Immed] ; AXXX OS | DC.W $AXXX ; OS XXXX | S [,AutoPop] ; AXXX ======================================================================== All displacements (∂, BD, OD) are hexadecimal values shown as a byte ($XX), word ($XXXX), or long ($XXXXXXXX) as appropriate. The *Scale is suppressed if 1. The Size is W or L. Note that effective address substitutions can only be made for "∂(An)", "BD,An", and "*±∂" cases. For all the effective address modes 5, 6n, 7n, and for A-traps, a coroutine (a procedure) whose address is specified by the LookupProc parameter is called by the Disassembler (if LookupProc is not NIL) to do the substitution (or A-trap comment) with a string returned by the proc. It is assumed that the proc pointed to by LookupProc is a level 1 Pascal proc declared as follows: PROCEDURE Lookup( PC: UNIV Ptr; {Addr of extension/trap word} BaseReg: LookupRegs; {Base register/lookup mode } Opnd: UNIV LongInt; {Trap word, PC addr, disp. } VAR S: DisAsmStr80); {Returned substitution } where TYPE DisAsmStr80 = String[80]; or in C, pascal void LookUp(Ptr PC, LookupRegs BaseReg, long Opnd, char *S); PC = Pointer to instruction extension word or A-trap word in the buffer pointed to by the Disassembler's FirstByte parameter. BaseReg = This determines the meaning of the Opnd value and supplies the base register for the "∂(An)", "BD,An", and "*±∂" cases. BaseReg may contain any one of the following values: _A0_ = 0 ==> A0 _A1_ = 1 ==> A1 _A2_ = 2 ==> A2 _A3_ = 3 ==> A3 _A4_ = 4 ==> A4 _A5_ = 5 ==> A5 _A6_ = 6 ==> A6 _A7_ = 7 ==> A7 _PC_ = 8 ==> PC-relative (special case) _ABS_ = 9 ==> Abs addr (special case) _TRAP_ = 10 ==> Trap word (special case) For absolute addressing (modes 70 and 71), BaseReg contains _ABS_. For A-traps, BaseReg would contain _TRAP_. Opnd = The contents of this LongInt is determined by the BaseReg parameter just described. For BaseReg = _TRAP_ (A-traps): Opnd is the entire trap word. The high order 16 bits of Opnd are zero. For BaseReg = _ABS_ (absolute effective address): Opnd contains the (extended) 32-bit address specifed by the instruction's effective address. Such addresses would generally be used to reference low memory globals on a Macintosh. For BaseReg = _PC_ (PC-relative effective address): Opnd contains the 32-bit address represented by "*±∂" adjusted by the Disassembler's DstAdjust parameter. For BaseReg = _An_ (effective address with a base register): Opnd contains the (sign-extended) 32-bit (base) displacement from the instruction's effective address. In the Macintosh environment, a BaseReg specifying A5 implies either global data references or Jump Table references. Positive Opnd values with an A5 BaseReg thus mean Jump Table references, while a negative offset would mean a global data reference. Base registers of A6 or A7 would usually mean local data. S = Pascal string returned from Lookup containing the effective address substitution string or a trap name for A-traps. S is set to null PRIOR to calling Lookup. If it is still null on return, the string is not used. If not null, then for A-traps, the returned string is used as a opcode string. In all other cases the string is substituted as shown in the above table. Depending on the application, the caller has three choices on how to use the Disassembler and an associated Lookup proc: (1). The caller can call just the Disassembler and provide his own Lookup proc. In that case the calling conventions discussed above must be followed. (2). The caller can provide NIL for the LookupProc parameter, in which case, NO Lookup proc will be called. (3). The caller can call first InitLookup (described below, a proc provided with this unit) and pass the address of this unit's standard Lookup proc when Disassembler is called. In this case all the control logic to determine the kind of substitution to be done is provided for the caller and all that need to be provided by the user are routines to look up any or all of the following: • PC-relative references • Jump Table references • Absolute address references • Trap names • References with offsets from base registers */ æKY endOfModule æFc DisAsmLookup.h æT Function æD char *endOfModule(void *address,void *limit,char *symbol,void **nextModule); æDT char myVariable = endOfModule((void *)address,(void *)limit,(char *)symbol, (void *)*nextModule); æC /* Check to see if the specified memory address, contains a RTS, JMP (A0) or RTD #n instruction immediately followed by a valid MacsBug symbol. These sequences are the only ones which can determine an end of module when MacsBug symbols are present. During the check, the instruction and its following MacsBug symbol must be fully contained in the bytes starting at the specified address parameter, up to, but not including, the byte pointed to by the limit parameter. If the end of module is NOT found, then NULL is returned as the function's result. However, if a end of module is found, the MacsBug symbol is returned in symbol (if it is not NULL) as a null terminated Pascal string (with trailing blanks removed), and the functions returns the pointer to the start of the MacsBug symbol (i.e., address+2 for RTS or JMP (A0) and address+4 for RTD #n). This address may then be used as in input parameter to showMacsBugSymbol to convert the MacsBug symbol to a Disassembler operand string. Also returned in nextModule is where we think the FOLLOWING module begins. In the "old style" cases (see validMacsBugSymbol) this will always be 8 or 16 bytes after the input address. For new style the Apple Pascal and C cases this will depend on the symbol length, existence of a pad byte, and size of the constant (literal) area. See validMacsBugSymbol for a description of valid MacsBug symbol formats. */ æKY InitLookup æFc DisAsmLookup.h æT Function æD pascal void InitLookup(Ptr PCRelProc,Ptr JTOffProc,Ptr TrapProc,Ptr AbsAddrProc, Ptr IdProc); æDT InitLookup((Ptr)PCRelProc,(Ptr)JTOffProc,(Ptr)TrapProc, (Ptr)AbsAddrProc,(Ptr)IdProc); æC /* Prepare for use of this unit's Lookup proc. When Disassembler is called and the address of this unit's Lookup proc is specified, then for PC-relative, Jump Table references, A-traps, absolute addresses, and offsets from a base register, the associated level 1 Pascal proc specified here is called (if not NULL -- all five addresses are preset to NULL). The calls assume the following declarations for these procs (see Lookup, below for further details): PROCEDURE PCRelProc(Address: UNIV LongInt; VAR S: UNIV DisAsmStr80); PROCEDURE JTOffProc(A5JTOffset: UNIV Integer; VAR S: UNIV DisAsmStr80); PROCEDURE TrapNameProc(TrapWord: UNIV Integer; VAR S: UNIV DisAsmStr80); PROCEDURE AbsAddrProc(AbsAddr: UNIV LongInt; VAR S: UNIV DisAsmStr80); PROCEDURE IdProc(BaseReg: LookupRegs; Offset: UNIV LongInt; VAR S: UNIV DisAsmStr80); or in C, pascal void PCRelProc(long Address, char *S) pascal void JTOffProc(short A5JTOffset, char *S) pascal void TrapNameProc(unsigned short TrapWord, char *S) pascal void AbsAddrProc(long AbsAddr, char *S) pascal void IdProc(LookupRegs BaseReg, long Offset, char *S) Note: InitLookup contains initialized data which requires initializing at load time (this is of concern only to users with assembler main programs. */ æKY Lookup æFc DisAsmLookup.h æT Function æD pascal void Lookup(Ptr PC,LookupRegs BaseReg,long Opnd,char *S); æDT Lookup((Ptr)PC,(LookupRegs)BaseReg,(long)Opnd,(char *)S); æC /* This is a standard Lookup proc available to the caller for calls to the Disassembler. If the caller elects to use this proc, then InitLookup MUST be called prior to any calls to the Disassembler. All the logic to determine the type of lookup is done by this proc. For PC-relative, Jump Table references, A-traps, absolute addresses, and offsets from a base register, the associated level 1 Pascal proc specified in the InitLookup call (if not NULL) is called. This scheme simplifies the Lookup mechanism by allowing the caller to deal with just the problems related to the application. */ æKY LookupRegs _A0_ _A1_ _A2_ _A3_ _A4_ _A5_ _A6_ _A7_ _PC_ _ABS_ _TRAP_ æFc DisAsmLookup.h æD enum {_A0_,_A1_,_A2_,_A3_,_A4_,_A5_,_A6_,_A7_,_PC_,_ABS_,_TRAP_}LookupRegs; typedef unsigned char LookupRegs; æKY LookupTrapName æFc DisAsmLookup.h æT Function æD pascal void LookupTrapName(unsigned short TrapWord,char *S); æDT LookupTrapName((unsigned short)TrapWord,(char *)S); æC /* This is a procedure provided to allow conversion of a trap instruction (in TrapWord) to its corresponding trap name (in S). It is provided primarily for use with the Disassembler and its address may be passed to InitLookup above for use by this unit's Lookup routine. Alternatively, there is nothing prohibiting the caller from using it directly for other purposes or by some other lookup proc. Note: The tables in this proc make the size of this proc about 9500 bytes. The trap names are fully spelled out in upper and lower case. */ æKY ModifyOperand æFc DisAsmLookup.h æT Function æD pascal void ModifyOperand(char *operand); æDT ModifyOperand((char *)operand); æC /* Scan an operand string, i.e., the null terminated Pascal string returned by the Disassembler (null MUST be present here) and modify negative hex values to negated positive value. For example, $FFFF(A5) would be modified to -$0001(A5). The operand to be processed is passed as the function's parameter which is edited "in place" and returned to the caller. This routine is essentially a pattern matcher and attempts to only modify 2, 4, and 8 digit hex strings in the operand that "might" be offsets from a base register. If the matching tests are passed, the same number of original digits are output (because that indicates a value's size -- byte, word, or long). For a hex string to be modified, the following tests must be passed: • There must have been exactly 2, 4, or 8 digits. Only hex strings $XX, $XXXX, and $XXXXXXXX are possible candidates because that is the only way the Disassembler generates offsets. • Hex string must be delimited by a "(" or a ",". The "(" allows offsets for $XXXX(An,...) and $XX(An,Xn) addressing modes. The comma allows for the MC68020 addressing forms. • The "$X..." must NOT be preceded by a "±". This eliminates the possibility of modifying the offset of a PC-relative addressing mode always generated in the form "*±$XXXX". • The "$X..." must NOT be preceded by a "#". This eliminates modifying immediate data. • Value must be negative. Negative values are the only values we modify. A value $FFFF is modified to -$0001. */ æKY showMacsBugSymbol æFc DisAsmLookup.h æT Function æD char *showMacsBugSymbol(char *symStart,void *limit,char *operand,short *bytesUsed); æDT char myVariable = showMacsBugSymbol((char *)symStart,(void *)limit,(char *)operand, (short *)bytesUsed); æC /* Format a MacsBug symbol as a operand of a DC.B directive. The first one or two bytes of the symbol are generated as $80+'c' if they have there high high bits set. All other characters are shown as characters in a string constant. The pad byte, if present, is one is also shown as $00. This routine is called to check that the bytes pointed to by symStart represent a valid MacsBug symbol. The symbol must be fully contained in the bytes starting at symStart, up to, but not including the byte pointed to by the limit parameter. When called, showMacsBugSymbol assumes that symStart is pointing at a valid MacsBug symbol as validated by the validMacsBugSymbol or endOfModule routines. As with validMacsBugSymbol, the symbol must be fully contained in the bytes starting at symStart up to, but not including, the byte pointed to by the end parameter. The string is returned in the 'operand' parameter as a null terminated Pascal string. The function also returns a pointer to this string as its return value (NULL is returned only if the byte pointed to by the limit parameter is reached prior to processing the entire symbol -- which should not happen if properly validated). The number of bytes used for the symbol is returned in bytesUsed. Due to the way MacsBug symbols are encoded, bytesUsed may not necessarily be the same as the length of the operand string. A valid MacsBug symbol consists of the characters '_', '%', spaces, digits, and upper/lower case letters in a format determined by the first two bytes of the symbol as described in the validMacsBugSymbol routine. */ æKY validMacsBugSymbol æFc DisAsmLookup.h æT Function æD char *validMacsBugSymbol(char *symStart,void *limit,char *symbol); æDT char myVariable = validMacsBugSymbol((char *)symStart,(void *)limit, (char *)symbol); æC /* Check that the bytes pointed to by symStart represents a valid MacsBug symbol. The symbol must be fully contained in the bytes starting at symStart, up to, but not including, the byte pointed to by the limit parameter. If a valid symbol is NOT found, then NULL is returned as the function's result. However, if a valid symbol is found, it is copied to symbol (if it is not NULL) as a null terminated Pascal string, and return a pointer to where we think the FOLLOWING module begins. In the "old style" cases (see below) this will always be 8 or 16 bytes after the input symStart. For new style Apple Pascal and C cases this will depend on the symbol length, existence of a pad byte, and size of the constant (literal) area. In all cases, trailing blanks are removed from the symbol. A valid MacsBug symbol consists of the characters '_', '%', spaces, digits, and upper/lower case letters in a format determined by the first two bytes of the symbol as follows: 1st byte | 2nd byte | Byte | Range | Range | Length | Comments ============================================================================== $20 - $7F | $20 - $7F | 8 | "Old style" MacsBug symbol format $A0 - $FF | $20 - $7F | 8 | "Old style" MacsBug symbol format ------------------------------------------------------------------------------ $20 - $7F | $80 - $FF | 16 | "Old style" MacApp symbol ab==>b.a $A0 - $FF | $80 - $FF | 16 | "Old style" MacApp symbol ab==>b.a ------------------------------------------------------------------------------ $80 | $01 - $FF | n | n = 2nd byte (Apple Compiler symbol) $81 - $9F | $00 - $FF | m | m = 1st byte & $7F (Apple Compiler symbol) ============================================================================== The formats are determined by whether bit 7 is set in the first and second bytes. This bit will removed when we find it or'ed into the first and/or second valid symbol characters. The first two formats in the above table are the basic "old style" (pre- existing) MacsBug formats. The first byte may or may not have bit 7 set the second byte is a valid symbol character. The first byte (with bit 7 removed) and the next 7 bytes are assumed to comprise the symbol. The second pair of formats are also "old style" formats, but used for MacApp symbols. Bit 7 set in the second character indicates these formats. The symbol is assumed to be 16 bytes with the second 8 bytes preceding the first 8 bytes in the generated symbol. For example, 12345678abcdefgh represents the symbol abcdefgh.12345678. The last pair of formats are reserved by Apple and generated by the MPW Pascal and C compilers. In these cases the value of the first byte is always between $80 and $9F, or with bit 7 removed, between $00 and $1F. For $00, the second byte is the length of the symbol with that many bytes following the second byte (thus a max length of 255). Values $01 to $1F represent the length itself. A pad byte may follow these variable length cases if the symbol does not end on a word boundary. Following the symbol and the possible pad byte is a word containing the size of the constants (literals) generated by the compiler. Note that if symStart actually does point to a valid MacsBug symbol, then you may use showMacsBugSymbol to convert the MacsBug symbol bytes to a string that could be used as a DC.B operand for disassembly purposes. This string explicitly shows the MacsBug symbol encodings. */ æKY DiskInit.h æKL DIBadMount dibadmount DIFormat DILoad DIUnload DIVerify dizero DIZero HFSDefaults æKY HFSDefaults æFc DiskInit.h æT struct æD struct HFSDefaults { char sigWord[2]; /* signature word*/ long abSize; /* allocation block size in bytes*/ long clpSize; /* clump size in bytes*/ long nxFreeFN; /* next free file number*/ long btClpSize; /* B-Tree clump size in bytes*/ short rsrv1; /* reserved*/ short rsrv2; /* reserved*/ short rsrv3; /* reserved*/ }; typedef struct HFSDefaults HFSDefaults; æC »Formatting Hierarchical Volumes The Disk Initialization Package must set certain volume characteristics when placing a hierarchical file directory on a volume. Default values for these volume characteristics are stored in the 128K ROM; this section is for advanced programmers who want to substitute their own values. The record containing the default values, if defined in Pascal, would look like this: TYPE HFSDefaults = PACKED RECORD sigWord: ARRAY[1..2] OF CHAR; {signature word} abSize: LONGINT; {allocation block size in bytes} clpSize: LONGINT; {clump size in bytes} nxFreeFN: LONGINT; {next free file number} btClpSize: LONGINT; {B*-Tree clump size in bytes} rsrv1: INTEGER; {reserved} rsrv2: INTEGER; {reserved} rsrv3: INTEGER; {reserved} END; The default values for these fields are as follows: Field Default value sigWord 'BD' abSize 0 clpSize 4 * abSize nxFreeFN 16 btClpSize 0 To supply your own values for these fields, create a similar, nonrelocatable record containing the desired values and place a pointer to it in the global variable FmtDefaults. To restore the system defaults, simply clear FmtDefaults. The sigWord must equal 'BD' (meaning “big disk”) for the volume to be recognized as a hierarchical volume. If the specified allocation block size is 0, the allocation block size is calculated according to the size of the volume: abSize = (1 + (volSize in blocks / 64K)) * 512 bytes If the specified B*-tree clump size is 0, the clump size for both the catalog and extent trees is calculated according to the size of the volume: btClpSize = (volSize in blocks)/128 * 512bytes æKY DILoad æFc DiskInit.h æT Function æD pascal void DILoad(void); æDT DILoad()(void); æMM æRI II-396 æC Assembly-language note: The trap macro for the Disk Initialization Package is _Pack2. The routine selectors are as follows: diBadMount .EQU 0 diLoad .EQU 2 diUnload .EQU 4 diFormat .EQU 6 diVerify .EQU 8 diZero .EQU 10 DILoad reads the Disk Initialization Package, and its associated dialog and dialog items, from the system resource file into memory and makes them unpurgeable. Note: DIFormat, DIVerify, and DIZero don’t need the dialog, so if you use only these routines you can call the Resource Manager function GetResource to read just the package resource into memory (and the Memory Manager procedure HNoPurge to make it unpurgeable). æKY DIUnload æFc DiskInit.h æT Function æD pascal void DIUnload(void); æDT DIUnload()(void); æMM æRI II-396 æC Assembly-language note: The trap macro for the Disk Initialization Package is _Pack2. The routine selectors are as follows: diBadMount .EQU 0 diLoad .EQU 2 diUnload .EQU 4 diFormat .EQU 6 diVerify .EQU 8 diZero .EQU 10 DIUnload makes the Disk Initialization Package (and its associated dialog and dialog items) purgeable. æKY DIBadMount æFc DiskInit.h æT Function æD pascal short DIBadMount(Point where,long evtMessage); æDT short myVariable = DIBadMount((Point) where,(long) evtMessage); æRI DIBadMount function II-396, N70-1, P-34, 168 æC Assembly-language note: The trap macro for the Disk Initialization Package is _Pack2. The routine selectors are as follows: diBadMount .EQU 0 diLoad .EQU 2 diUnload .EQU 4 diFormat .EQU 6 diVerify .EQU 8 diZero .EQU 10 Call DIBadMount when a disk-inserted event occurs if the result code in the high-order word of the associated event message indicates an error (that is, the result code is other than noErr). Given the event message in evtMessage, DIBadMount evaluates the result code and either ejects the disk or lets the user initialize and name it. The low-order word of the event message contains the drive number. The where parameter specifies the location (in global coordinates) of the top left corner of the dialog box displayed by DIBadMount. If the result code passed is extFSErr, memFullErr, nsDrvErr, paramErr, or volOnLinErr, DIBadMount simply ejects the disk from the drive and returns the result code. If the result code ioErr, badMDBErr, or noMacDskErr is passed, the error can be corrected by initializing the disk; DIBadMount displays a dialog box that describes the problem and asks whether the user wants to initialize the disk. For the result code ioErr, the dialog box shown in Figure 1 is displayed. (This happens if the disk is brand new.) For badMDBErr and noMacDskErr, DIBadMount displays a similar dialog box in which the description of the problem is “This disk is damaged” and “This is not a Macintosh disk”, respectively. •••Refer to Figure 1.••• Figure 1–Disk Initialization Dialog for IOErr Note: Before presenting the disk initialization dialog, DIBadMount checks whether the drive contains an already mounted volume; if so, it ejects the disk and returns 2 as its result. This will happen rarely and may reflect an error in your program (for example, you forgot to call DILoad and the user had to switch to the disk containing the system resource file). If the user responds to the disk initialization dialog by clicking the Eject button, DIBadMount ejects the disk and returns 1 as its result. If the Initialize button is clicked, a box displaying the message “Initializing disk...” appears, and DIBadMount attempts to initialize the disk. If initialization fails, the disk is ejected and the user is informed as shown in Figure 2; after the user clicks OK, DIBadMount returns a negative result code ranging from firstDskErr to lastDskErr, indicating that a low-level disk error occurred. •••Refer to Figure 2.••• Figure 2–Initialization Failure Dialog If the disk is successfully initialized, the dialog box in Figure 3 appears. After the user names the disk and clicks OK, DIBadMount mounts the volume by calling the File Manager function MountVol and returns MountVol’s result code (noErr if no error occurs). •••Refer to Figure 3.••• Figure 3–Dialog for Naming a Disk Result codes noErr No error extFSErr External file system memFullErr Not enough room in heap zone nsDrvErr No such drive paramErr Bad drive number volOnLinErr Volume already on-line firstDskErr Low-level disk error through lastDskErr Other results 1 User clicked Eject 2 Mounted volume in drive æKY dibadmount æFc DiskInit.h æT Function æD OSErr dibadmount(Point *where,long evtMessage); æDT OSErr myVariable = dibadmount((Point *) where,(long) evtMessage); æC Assembly-language note: The trap macro for the Disk Initialization Package is _Pack2. The routine selectors are as follows: diBadMount .EQU 0 diLoad .EQU 2 diUnload .EQU 4 diFormat .EQU 6 diVerify .EQU 8 diZero .EQU 10 Call DIBadMount when a disk-inserted event occurs if the result code in the high-order word of the associated event message indicates an error (that is, the result code is other than noErr). Given the event message in evtMessage, DIBadMount evaluates the result code and either ejects the disk or lets the user initialize and name it. The low-order word of the event message contains the drive number. The where parameter specifies the location (in global coordinates) of the top left corner of the dialog box displayed by DIBadMount. If the result code passed is extFSErr, memFullErr, nsDrvErr, paramErr, or volOnLinErr, DIBadMount simply ejects the disk from the drive and returns the result code. If the result code ioErr, badMDBErr, or noMacDskErr is passed, the error can be corrected by initializing the disk; DIBadMount displays a dialog box that describes the problem and asks whether the user wants to initialize the disk. For the result code ioErr, the dialog box shown in Figure 1 is displayed. (This happens if the disk is brand new.) For badMDBErr and noMacDskErr, DIBadMount displays a similar dialog box in which the description of the problem is “This disk is damaged” and “This is not a Macintosh disk”, respectively. •••Refer to Figure 1.••• Figure 1–Disk Initialization Dialog for IOErr Note: Before presenting the disk initialization dialog, DIBadMount checks whether the drive contains an already mounted volume; if so, it ejects the disk and returns 2 as its result. This will happen rarely and may reflect an error in your program (for example, you forgot to call DILoad and the user had to switch to the disk containing the system resource file). If the user responds to the disk initialization dialog by clicking the Eject button, DIBadMount ejects the disk and returns 1 as its result. If the Initialize button is clicked, a box displaying the message “Initializing disk...” appears, and DIBadMount attempts to initialize the disk. If initialization fails, the disk is ejected and the user is informed as shown in Figure 2; after the user clicks OK, DIBadMount returns a negative result code ranging from firstDskErr to lastDskErr, indicating that a low-level disk error occurred. •••Refer to Figure 2.••• Figure 2–Initialization Failure Dialog If the disk is successfully initialized, the dialog box in Figure 3 appears. After the user names the disk and clicks OK, DIBadMount mounts the volume by calling the File Manager function MountVol and returns MountVol’s result code (noErr if no error occurs). •••Refer to Figure 3.••• Figure 3–Dialog for Naming a Disk Result codes noErr No error extFSErr External file system memFullErr Not enough room in heap zone nsDrvErr No such drive paramErr Bad drive number volOnLinErr Volume already on-line firstDskErr Low-level disk error through lastDskErr Other results 1 User clicked Eject 2 Mounted volume in drive æKY DIFormat æFc DiskInit.h æT Function æD pascal OSErr DIFormat(short drvNum); æDT OSErr myVariable = DIFormat((short) drvNum); æMM æRI II-398 æC Assembly-language note: The trap macro for the Disk Initialization Package is _Pack2. The routine selectors are as follows: diBadMount .EQU 0 diLoad .EQU 2 diUnload .EQU 4 diFormat .EQU 6 diVerify .EQU 8 diZero .EQU 10 DIFormat formats the disk in the drive specified by the given drive number and returns a result code indicating whether the formatting was completed successfully or failed. Formatting a disk consists of writing special information onto it so that the Disk Driver can read from and write to the disk. Result codes noErr No error firstDskErr Low-level disk error through lastDskErr æKY DIVerify æFc DiskInit.h æT Function æD pascal OSErr DIVerify(short drvNum); æDT OSErr myVariable = DIVerify((short) drvNum); æMM æRI II-398 æC Assembly-language note: The trap macro for the Disk Initialization Package is _Pack2. The routine selectors are as follows: diBadMount .EQU 0 diLoad .EQU 2 diUnload .EQU 4 diFormat .EQU 6 diVerify .EQU 8 diZero .EQU 10 DIVerify verifies the format of the disk in the drive specified by the given drive number; it reads each bit from the disk and returns a result code indicating whether all bits were read successfully or not. DIVerify doesn’t affect the contents of the disk itself. Result codes noErr No error firstDskErr Low-level disk error through lastDskErr æKY DIZero æFc DiskInit.h æT Function æD pascal OSErr DIZero(short drvNum,const Str255 volName); æDT OSErr myVariable = DIZero((short) drvNum,(const Str255) volName); æMM æRT 70 æRI II-399, N70-2 æC Assembly-language note: The trap macro for the Disk Initialization Package is _Pack2. The routine selectors are as follows: diBadMount .EQU 0 diLoad .EQU 2 diUnload .EQU 4 diFormat .EQU 6 diVerify .EQU 8 diZero .EQU 10 On the unmounted volume in the drive specified by the given drive number, DIZero writes the volume information, a block map, and a file directory as for a volume with no files; the volName parameter specifies the volume name to be included in the volume information. This is the last step in initialization (after formatting and verifying) and makes any files that are already on the volume permanently inaccessible. If the operation fails, DIZero returns a result code indicating that a low-level disk error occurred; otherwise, it mounts the volume by calling the File Manager function MountVol and returns MountVol’s result code (noErr if no error occurs). Result codes noErr No error badMDBErr Bad master directory block extFSErr External file system ioErr I/O error memFullErr Not enough room in heap zone noMacDskErr Not a Macintosh disk nsDrvErr No such drive paramErr Bad drive number volOnLinErr Volume already on-line firstDskErr Low-level disk error through lastDskErr æKY dizero æFc DiskInit.h æT Function æD OSErr dizero(short drvnum,char *volName); æDT OSErr myVariable = dizero((short) drvnum,(char *) volName); æC æKY Disks.h æKL DiskEject DriveStatus SetTagBuffer DrvSts DrvSts2 æKY DrvSts æFc Disks.h æT struct æD struct DrvSts { short track; char writeProt; char diskInPlace; char installed; char sides; QElemPtr qLink; short qType; short dQDrive; short dQRefNum; short dQFSID; char twoSideFmt; char needsFlush; short diskErrs; }; typedef struct DrvSts DrvSts; æC æKY DrvSts2 æFc Disks.h æT struct æD struct DrvSts2 { short track; char writeProt; char diskInPlace; char installed; char sides; QElemPtr qLink; short qType; short dQDrive; short dQRefNum; short dQFSID; short driveSize; short driveS1; short driveType; short driveManf; short driveChar; char driveMisc; }; typedef struct DrvSts2 DrvSts2; æC æKY DiskEject æFc Disks.h æT Function æD pascal OSErr DiskEject(short drvNum); æDT OSErr myVariable = DiskEject((short) drvNum); æMM æRI II-214 æC [Not in ROM] Assembly-language note: DiskEject is equivalent to a Control call with csCode equal to the global constant ejectCode. DiskEject ejects the disk from the internal drive if drvNum is 1, or from the external drive if drvNum is 2. Result codes noErr No error nsDrvErr No such drive æKY SetTagBuffer æFc Disks.h æT Function æD pascal OSErr SetTagBuffer(Ptr buffPtr); æDT OSErr myVariable = SetTagBuffer((Ptr) buffPtr); æMM æRI II-214 æC [Not in ROM] Assembly-language note: SetTagBuffer is equivalent to a Control call with csCode equal to the global constant tgBuffCode. An application can change the information used in the file tags buffer by calling SetTagBuffer. The buffPtr parameter points to a buffer that contains the information to be used. If buffPtr is NIL, the information in the file tags buffer isn’t changed. If buffPtr isn’t NIL, every time the Disk Driver reads a sector from the disk, it stores the file tags in the file tags buffer and in the buffer pointed to by buffPtr. Every time the Disk Driver writes a sector onto the disk, it reads 12 bytes from the buffer pointed to by buffPtr, places them in the file tags buffer, and then writes them onto the disk. The contents of the buffer pointed to by buffPtr are overwritten at the end of every read request (which can be composed of a number of sectors) instead of at the end of every sector. Each read request places 12 bytes in the buffer for each sector, always beginning at the start of the buffer. This way an application can examine the file tags for a number of sequentially read sectors. If a read request is composed of a number of sectors, the Disk Driver places 12 bytes in the buffer for each sector. For example, for a read request of five sectors, the Disk Driver will place 60 bytes in the buffer. Result codes noErr No error æKY DriveStatus æFc Disks.h æT Function æD pascal OSErr DriveStatus(short drvNum,DrvSts *status); æDT OSErr myVariable = DriveStatus((short) drvNum,(DrvSts *) status); æMM æRI II-215 æC [Not in ROM] Assembly-language note: DriveStatus is equivalent to a Status call with csCode equal to the global constant drvStsCode; status is returned in csParam through csParam+21. DriveStatus returns information about the internal drive if drvNum is 1, or about the external drive if drvNum is 2. The information is returned in a record of type DrvSts: TYPE DrvSts = RECORD track: INTEGER; {current track} writeProt: SignedByte; {bit 7=1 if volume is locked} diskInPlace: SignedByte; {disk in place} installed: SignedByte; {drive installed} sides: SignedByte; {bit 7=0 if single-side drive} qLink: QElemPtr; {next queue entry} qType: INTEGER; {reserved for future use} dQDrive: INTEGER; {drive number} dQRefNum: INTEGER; {driver reference number} dQFSID: INTEGER; {file-system identifier} twoSideFmt: SignedByte; {-1 if two-sided disk} needsFlush: SignedByte; {reserved for future use} diskErrs: INTEGER {error count} END; The diskInPlace field is 0 if there’s no disk in the drive, 1 or 2 if there is a disk in the drive, or –4 to –1 if the disk was ejected in the last 1.5 seconds. The installed field is 1 if the drive is connected to the Macintosh, 0 if the drive might be connected to the Macintosh, and –1 if the drive isn’t installed. The value of twoSideFmt is valid only when diskInPlace=2. The value of diskErrs is incremented every time an error occurs internally within the Disk Driver. Result codes noErr No error nsDrvErr No such drive æKY Editions.h æKL AssociateSection CallEditionOpenerProc CallFormatIOProc CloseEdition CreateEditionContainerFile DeleteEditionContainerFile EditionHasFormat FindEditionContainerDialog GetEditionFormatMark GetEditionInfo GetEditionOpenerProc GetLastEditionContainerUsed GetStandardFormats GotoPublisherSection InitEditionPack IsRegisterSection NewPublisherDialog NewPublisherExpDialog NewSection NewSubscriberDialog NewSubscriberExpDialog OpenEdition OpenNewEdition ReadEdition RegisterSection SectionOptionsDialog SectionOptionsExpDialog SetEditionFormatMark SetEditionOpenerProc UnRegisterSection WriteEdition EditionContainerSpec EditionInfoRecord EditionOpenerParamBlock EditionOpenerProcPtr EditionOpenerVerb EditionRefNum eoCanSubscribe eoClose eoCloseNew eoOpen eoOpenNew ExpDlgHookProcPtr ExpModalFilterProcPtr FormatIOParamBlock FormatIOProcPtr FormatIOVerb FormatType ioHasFormat ioNewFormat ioReadFormat ioWriteFormat kFormatLengthUnknown kFormatListFormat kPartNumberUnknown kPartsNotUsed kPreviewFormat kPreviewHeight kPreviewWidth kPublisherDocAliasFormat NewPublisherReply NewSubscriberReply pumOnSave pumSuspend rSectionType sectionCancelMsgID sectionEventMsgClass SectionHandle SectionOptionsReply SectionPtr sectionReadMsgID SectionRecord sectionScrollMsgID SectionType sectionWriteMsgID stPublisher stSubscriber sumAutomatic sumOnRequestOnly TimeStamp UpdateMode æKY rSectionType æFc Editions.h æT #define æD /* resource types */ #define rSectionType 'sect' /* ResType of saved SectionRecords */ æC æKY stSubscriber æFc Editions.h æT #define æD /* ssection types */ #define stSubscriber 0x01 æC æKY stPublisher æFc Editions.h æT #define æD #define stPublisher 0x0A æC æKY sumAutomatic æFc Editions.h æT #define æD /* update modes */ #define sumAutomatic 0 /* subscriber update mode - Automatic */ æC æKY sumOnRequestOnly æFc Editions.h æT #define æD #define sumOnRequestOnly 1 /* subscriber update mode - OnRequestOnly */ æC æKY pumOnSave æFc Editions.h æT #define æD #define pumOnSave 0 /* publisher update mode - OnSave */ æC æKY pumSuspend æFc Editions.h æT #define æD #define pumSuspend 1 /* publisher update mode - OnRequestOnly */ æC æKY kPartsNotUsed æFc Editions.h æT #define æD #define kPartsNotUsed 0 æC æKY kPartNumberUnknown æFc Editions.h æT #define æD #define kPartNumberUnknown (-1) æC æKY kPreviewWidth æFc Editions.h æT #define æD #define kPreviewWidth 120 æC æKY kPreviewHeight æFc Editions.h æT #define æD #define kPreviewHeight 120 æC æKY kPublisherDocAliasFormat æFc Editions.h æT #define æD #define kPublisherDocAliasFormat 'alis' æC æKY kPreviewFormat æFc Editions.h æT #define æD #define kPreviewFormat 'prvw' æC æKY kFormatListFormat æFc Editions.h æT #define æD #define kFormatListFormat 'fmts' æC æKY kFormatLengthUnknown æFc Editions.h æT #define æD #define kFormatLengthUnknown (-1) æC æKY sectionEventMsgClass æFc Editions.h æT #define æD /* the following fields are private and set up by RegisterSection Section events now arrive in the message buffer using the new AppleEvent format. The direct object parameter is an aeTemporaryIDParamType ('tid '). The temporary ID's type is rSectionType ('sect') and the 32-bit value is a SectionHandle. */ #define sectionEventMsgClass 'sect' æC æKY sectionReadMsgID æFc Editions.h æT #define æD #define sectionReadMsgID 'read' æC æKY sectionWriteMsgID æFc Editions.h æT #define æD #define sectionWriteMsgID 'writ' æC æKY sectionScrollMsgID æFc Editions.h æT #define æD #define sectionScrollMsgID 'scrl' æC æKY sectionCancelMsgID æFc Editions.h æT #define æD #define sectionCancelMsgID 'cncl' æC æKY FormatIOVerb ioHasFormat ioReadFormat ioNewFormat ioWriteFormat æFc Editions.h æT enum æD enum {ioHasFormat,ioReadFormat,ioNewFormat,ioWriteFormat}; typedef unsigned char FormatIOVerb; æC æKY EditionOpenerVerb eoOpen eoClose eoOpenNew eoCloseNew eoCanSubscribe æFc Editions.h æT enum æD enum {eoOpen,eoClose,eoOpenNew,eoCloseNew,eoCanSubscribe}; typedef unsigned char EditionOpenerVerb; æC æKY UpdateMode æFc Editions.h æT typedef æD typedef short UpdateMode; /* sumAutomatic, pumSuspend, etc */ æC æKY SectionType æFc Editions.h æT typedef æD typedef char SectionType; /* one byte, stSubscriber or stPublisher */ æC æKY TimeStamp æFc Editions.h æT typedef æD typedef unsigned long TimeStamp; /* seconds since 1904 */ æC æKY FormatType æFc Editions.h æT typedef æD typedef unsigned long FormatType; /* similar to ResType */ æC æKY EditionRefNum æFc Editions.h æT typedef æD typedef Handle EditionRefNum; /* used in Edition I/O */ æC æKY ExpModalFilterProcPtr æFc Editions.h æT typedef æD typedef pascal Boolean (*ExpModalFilterProcPtr) (DialogPtr theDialog, EventRecord *theEvent, short itemOffset, short *itemHit, Ptr yourDataPtr); æC æKY ExpDlgHookProcPtr æFc Editions.h æT typedef æD typedef pascal short (*ExpDlgHookProcPtr) (short itemOffset, short itemHit, DialogPtr theDialog, Ptr yourDataPtr); æC æKY FormatIOProcPtr æFc Editions.h æT typedef æD typedef pascal short (*FormatIOProcPtr) (FormatIOVerb selector, FormatIOParamBlock *PB); æC æKY EditionOpenerProcPtr æFc Editions.h æT typedef æD typedef pascal short (*EditionOpenerProcPtr) (EditionOpenerVerb selector, FormatIOParamBlock *PB); æC æKY SectionRecord SectionPtr SectionHandle æFc Editions.h æT struct æD struct SectionRecord { signed char version; /* always 0x01 in system 7.0 */ SectionType kind; /* stSubscriber or stPublisher */ UpdateMode mode; /* auto or manual */ TimeStamp mdDate; /* last change in document */ long sectionID; /* app. specific, unique per document */ long refCon; /* application specific */ AliasHandle alias; /* handle to Alias Record */ long subPart; /* which part of container file */ struct SectionRecord **nextSection; /* for linked list of app's Sections */ Handle controlBlock; /* used internally */ EdtionRefNum refNum; /* used internally */ }; typedef struct SectionRecord SectionRecord; typedef SectionRecord *SectionPtr, **SectionHandle; æC æKY EditionContainerSpec æFc Editions.h æT struct æD struct EditionContainerSpec { CanonicalFileSpec theFile; Short theFileScript; long thePart; Str31 thePartName; Short thePartScript; }; typedef struct EditionContainerSpec EditionContainerSpec; æC æKY EditionInfoRecord æFc Editions.h æT struct æD struct EditionInfoRecord { TimeStamp crDate; /* date EditionContainer was created */ TimeStamp mdDate; /* date of last change */ OSType fdCreator; /* file creator */ OSType fdType; /* file type */ EditionContainerSpec container; /* the Edition */ }; typedef struct EditionInfoRecord EditionInfoRecord; æC æKY NewPublisherReply æFc Editions.h æT struct æD struct NewPublisherReply { Boolean canceled; /* O */ Boolean replacing ; Boolean usePart; /* I */ Handle preview; /* I */ FormatType previewFormat; /* I */ EditionContainerSpec container; /* I/O */ }; typedef struct NewPublisherReply NewPublisherReply; æC æKY NewSubscriberReply æFc Editions.h æT struct æD struct NewSubscriberReply { Boolean canceled; /* O */ EditionContainerSpec container; /* I/O */ }; typedef struct NewSubscriberReply NewSubscriberReply; æC æKY SectionOptionsReply æFc Editions.h æT struct æD struct SectionOptionsReply { Boolean canceled; /* O */ Boolean changed; /* O */ SectionHandle sectionH; /* I */ ResType action; /* O */ }; typedef struct SectionOptionsReply SectionOptionsReply; æC æKY FormatIOParamBlock æFc Editions.h æT struct æD struct FormatIOParamBlock { long ioRefNum; FormatType format; long formatIndex; unsigned long offset; Ptr buffPtr; unsigned long buffLen; }; typedef struct FormatIOParamBlock FormatIOParamBlock; æC æKY EditionOpenerParamBlock æFc Editions.h æT struct æD struct EditionOpenerParamBlock { EditionInfoRecord info; SectionRecord **sectionH; CanonicalFileSpec *document; OSType fdCreator; long ioRefNum; FormatIOProcPtr ioProc; Boolean success; }; typedef struct EditionOpenerParamBlock EditionOpenerParamBlock; æC æKY InitEditionPack æFc Editions.h æT Function æTN A82D æD pascal OSErr InitEditionPack(void) = {0x3F3C,0x0010,0x303C,0x0100,0xA82D}; æDT OSErr myVariable = InitEditionPack()(void); æC You use the InitEditionPack function to initialize the Edition Manager. Before calling this funciton, be sure to determine if the Edition Manager is available on your system using the Gestalt function. The InitEditionPack function returns an error if the pack could not be loaded or is an old version. If the InitEditionPack does not return noErr, there is not enough system heap to load the package. Result codes noErr 0 No error editionMgrInitErr -450 Could not load package MemError NewHandle errors ResError GetResource errors æKY NewSection æFc Editions.h æT Function æTN A82D æD pascal OSErr NewSection(const EditionContinerSpec *container,const CanonicalFileSpec *sectionDocument, SectionType kind,long sectionID,UpdateMode initalMode,SectionHandle *sectionH) = {0x303C,0x0A02,0xA82D}; æDT OSErr myVariable = NewSection((const EditionContinerSpec *) container,(const CanonicalFileSpec *) sectionDocument,() SectionType kind,(long) sectionID,(UpdateMode) initalMode,(SectionHandle *) sectionH); æC You use the NewSection routine to create a new section (either publisher or subscriber), and alias record from the sectionDocument (document that contains a section) to the edition container. The NewSection function allocates two handles; one handle for the section record and another handle for the alias record. The container parameter is the name of the file which holds the edition.The sectionDocument parameter is the file name (in canonical form) of the document that contains section. The sectionDocument parameter can be NIL if your current document has never been saved. If so, remember to call the AssociateSection function when the user finally saves the document to update the alias record of a registered section. The kind parameter designates the type of section (publisher or subscriber) being created. Identify the section with a unique number in the sectionID parameter. The initialMode parameter contains the update mode for the section. For publishers, this is either the constant pumOnSave or pumSuspend and for subscribers this is either sumAutomatic or sumOnRequestOnly. If the NewSection function fails, the sectionH parameter is set to NIL. If the function is successful, sectionH contains the handle to the allocated section record. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed badSubPartErr -454 Bad container spec badSectionErr -451 Not valid SectionType multiplePublisherWrn -460 Already is a publisher MemError NewHandle errors ??? NewAlias errors The NewSection function internally calls the RegisterSection function to inform the Edition Manager about a section. æKY RegisterSection æFc Editions.h æT Function æTN A82D æD pascal OSErr RegisterSection(const CanonicalFileSpec *sectionDocument,SectionHandle sectionH, Boolean *aliasWasChanged) = {0x303C,0x0604,0xA82D}; æDT OSErr myVariable = RegisterSection((const CanonicalFileSpec *) sectionDocument,(SectionHandle) sectionH,( Boolean) * aliasWasChanged); æC The sectionDocument parameter is the file name of the document containing the section. This parameter cannot be NIL. The aliasWasChanged parameter returns TRUE if the alias for the edition container subscribed to is out of date. If so, the RegisterSection function updates the alias. This may occur if the file is moved to a new location or is renamed. The RegisterSection function adds the section record to the Edition Manager’s list of registered sections, and allocates a control block. After calling the RegisterSection function, the control block is either NIL or a valid control block. The control block is NIL if the RegisterSection function cannot locate the edition container being subscribed to. The RegisterSection function returns containerNotFoundWrn. You can compare control blocks for individual sections. If two sections contain the same control block value, these sections subscribe to the same edition. The Edition Manager needs to be informed when no sections are referencing a control block so that it can be deallocated. The control block maintains a count of how many sections are referencing it. Each time you use the UnRegisterSection function, the control block removes one from the number of sections. When the number of sections reaches 0, the control block is deallocated. For each section that you cannot register, you should display the document on the user’s screen, scroll to the location of the section, and then call the FindEditionContainerDialog function. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed badSectionErr -451 Not valid SectionType multiplePublisherWrn -460 Already is a publisher containerNotFoundWrn -461 Alias was not resolved ??? MatchAlias errors æKY UnRegisterSection æFc Editions.h æT Function æTN A82D æD pascal OSErr UnRegisterSection(SectionHandle sectionH) = {0x303C,0x0206,0xA82D}; æDT OSErr myVariable = UnRegisterSection((SectionHandle) sectionH); æC When a section needs to be disposed of because the document containing the section is closing, or the user is canceling the section, you need to call the UnRegisterSection function. The sectionH parameter is a handle to the section record for a given section. The UnRegisterSection function removes the section from the application’s list of registered sections. You can then dispose of the section record and alias record with standard memory and resource manager calls. Once unregistered, a section does not received any events and cannot read or write any data. Depending on your clipboard strategy, you may want to unregister sections that have been cut into the clipboard. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed fBsyErr Section doing I/O notRegisteredSectionErr -452 Not registered æKY IsRegisterSection æFc Editions.h æT Function æTN A82D æD pascal OSErr IsRegisterSection(const SectionHandle sectionH) = {0x303C,0x0208,0xA82D}; æDT OSErr myVariable = IsRegisterSection((const SectionHandle) sectionH); æC Each time your application receives a section event, your application must use the IsRegisteredSection function to verify that the event received is for a registered section. The sectionH parameter is a handle to the section record for a given section. The IsRegisteredSection function does not return a Boolean—noErr indicates that a section is registered. Result codes noErr 0 No error notRegisteredSectionErr -452 Not registered æKY FindEditionContainerDialog æFc Editions.h æT Function æTN A82D æD pascal OSErr FindEditionContainerDialog(const CanonicalFileSpec *sectionDocument, SectionHandle sectionH,Boolean *aliasWasChanged) = {0x303C,0x060A,0xA82D}; æDT OSErr myVariable = FindEditionContainerDialog((const CanonicalFileSpec *) sectionDocument,() SectionHandle sectionH,(Boolean *) aliasWasChanged); æC If an edition container cannot be found for a particular section during registration, use the FindEditionContainerDialog to resolve the alias record of the section. The sectionDocument parameter is the file name of the document containing a section in canonical form. This parameter cannot be NIL. If the FindEditionContainerDialog function is successful, the sectionH parameter contains the handle to the allocated section record. The aliasWasChanged parameter returns TRUE if the alias for the edition container that you are subscribing is out of date. This may occur if the file is moved to a new location or is renamed. The FindEditionContainerDialog functions assumes that your sections are contained within the linked list of registered sections.If the FindEditionContainerDialog function cannot locate the edition container, it will display a dialog box on the user’s screen. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed containerNotFoundWrn -461 Alias was not resolved multiplePublisherWrn -460 Already is a publisher ??? SelectAlias errors æKY AssociateSection æFc Editions.h æT Function æTN A82D æD pascal OSErr AssociateSection(SectionHandle sectionH,const CanonicalFileSpec *newSectionDocument) = {0x303C,0x040C,0xA82D}; æDT OSErr myVariable = AssociateSection((SectionHandle) sectionH,(const CanonicalFileSpec *) newSectionDocument); æC If a user renames a document that contains sections or pastes a portion of a document that contains a section into another document, use the AssociateSection to update the alias record. The sectionH parameter is a handle to the section record for a given section. The newSectionDocument contains the volume, folder and file name of the new document. The AssociateSection function calls the update alias on the alias record. Result codes noErr 0 No error ??? UpdateAlias errors æKY CreateEditionContainerFile æFc Editions.h æT Function æTN A82D æD pascal OSErr CreateEditionContainerFile(const CanonicalFileSpec *editionFile, OSType fdCreator,Short editionFileNameScript) = {0x303C,0x050E,0xA82D}; æDT OSErr myVariable = CreateEditionContainerFile((const CanonicalFileSpec *) editionFile,() OSType fdCreator,(Short) editionFileNameScript); æC Each time a user creates a new publisher section within a document to an edition that does not already exist, you use the CreateEditionContainerFile to create an empty edition container. The containerFile parameter contains the volume, folder and file name for the edition container being created. The fdCreator parameter contains the creator type for the edition. The CreateEditionContainerFile function creates an empty edition container file (it does not contain any formats). This function creates a file with type 'publ'. If your application has a bundle, you should designate an icon for it now. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed ??? PBHCreate errors ??? PBHOpen errors ??? PBWrite errors æKY DeleteEditionContainerFile æFc Editions.h æT Function æTN A82D æD pascal OSErr DeleteEditionContainerFile(const CanonicalFileSpec *editionFile) = {0x303C,0x0210,0xA82D}; æDT OSErr myVariable = DeleteEditionContainerFile((const CanonicalFileSpec *) editionFile); æC If a user cancels a publisher section within a document or closes a document containing a newly created publisher without saving, you need to remove the edition container using the DeleteEditionContainerFile function. The containerFile parameter contains the volume, folder and file name for the edition container being deleted. You should use the DeleteEditionContainerFile function even if there are subscribers to the edition. When a subscriber section tries to read in data, it receives an error. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed ??? PBHDelete errors æKY OpenEdition æFc Editions.h æT Function æTN A82D æD pascal OSErr OpenEdition(SectionHandle subscriberSectionH,EditionRefNum *refNum) = {0x303C,0x0412,0xA82D}; æDT OSErr myVariable = OpenEdition((SectionHandle) subscriberSectionH,(EditionRefNum *) refNum); æC You initiate the reading of data from an edition (for a subscriber), use the OpenEdition function. The subscriberSectionH parameter is a handle to the section record for a given section. The refnum parameter returns the reference number for the edition. Multiple subscribers can simultaneously read data from a single edition. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed permErr Not a subscriber æKY OpenNewEdition æFc Editions.h æT Function æTN A82D æD pascal OSErr OpenNewEdition(SectionHandle publisherSectionH,OSType fdCreator, const CanonicalFileSpec *publisherSectionDocument,EditionRefNum *refNum) = {0x303C,0x0814,0xA82D}; æDT OSErr myVariable = OpenNewEdition((SectionHandle) publisherSectionH,(OSType) fdCreator,( const CanonicalFileSpec) * publisherSectionDocument,(EditionRefNum *) refNum); æC To initiate the writing of data from a publisher to its edition container, use the OpenNewEdition function. The publisherSectionH parameter is the publisher section that you are writing to the edition. The fdCreator parameter is the Finder creator type of the new edition icon. The sectionDocument parameter is the document which contains the publisher. This parameter is used to create an alias from the edition to the document containing the publisher. If you pass NIL for sectionDocument, an alias is not made and the GotoPublisherSection function is unable to open the document containing the publisher. The refnum parameter returns the reference number for the edition. This parameter is necessary for subsequent calls to WriteEdition, SetEditionFormatMark, and CloseEdition to specify which publisher is writing its data to an edition. If the edition cannot be opened for writing because there is another publisher writing to it, or because the file system does not allow writing, an error is returned and refNum is set to NIL. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed wrPermErr Not a publisher notThePublisherWrn -462 Not the publisher ??? NewHandle errors ??? PBHCreate errors ??? PBHOpen errors ??? NewAlias errors æKY CloseEdition æFc Editions.h æT Function æTN A82D æD pascal OSErr CloseEdition(EditionRefNum whichEdition,Boolean success) = {0x303C,0x0316,0xA82D}; æDT OSErr myVariable = CloseEdition((EditionRefNum) whichEdition,(Boolean) success); æC After finishing reading from or writing to an edition, use the CloseEdition function to close the edition. The refnum parameter is the reference number for edition. Set the success parameter is set to TRUE if the edition successfully closes. If not, set this parameter to FALSE. When you are finished reading data from an edition and you are using the CloseEdition function, the EditionRefNum value becomes invalid. If the success parameter is set to TRUE, the CloseEdition function takes the modification date of the edition file that you have read in and puts it in the mdDate field of the subscriber’s section record. This indicates that the data contained in the edition and the subscriber section within the document are the same. If you set the success parameter to FALSE because you are unable to read the edition data (if there is not enough memory, or you didn’t find a format that you can read), the CloseEdition function closes the edition, but does not set the modification date field. This implies that the subscriber is not updated with the latest edition. When you have successfully finished writing data to an edition and you are using the CloseEdition function, you should set the success parameter to TRUE. When you do so, the data that you have written to the edition becomes available to any subscribers. The Edition Manager sends a SectionReadEvent to all current subscribers. The CloseEdition function sets the modification date (mdDate) of the edition to correspond to the modification date of the publisher’s section record. Each time a user edits a publisher within a document, you need to update the modification date (even if the data is not yet written). If you set the success parameter to FALSE because you are unable to successfully write data to the edition, the Edition Manager does not write any data to the edition. The data contained in the edition prior to writing is restored. SectionReadEvents are not sent to subscribers. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed rfNumErr Bad refNum ??? PBWrite errors ??? DisposHandle errors æKY EditionHasFormat æFc Editions.h æT Function æTN A82D æD pascal OSErr EditionHasFormat(EditionRefNum whichEdition,FormatType whichFormat, Size *length) = {0x303C,0x0618,0xA82D}; æDT OSErr myVariable = EditionHasFormat((EditionRefNum) whichEdition,(FormatType) whichFormat,( Size) * length); æC Use the EditionHasFormat function to find out in which formats the edition data is available. The whichEdition parameter is the reference number for the edition. The whichFormat parameter indicates the format type that you are requesting. Apple Computer recommends that you request formats in order of preference. Upon return of the EditionHasFormat function, the length parameter contains the length of the format for the edition you are specifying. If the requested format is available, this function returns noErr and the length field returns the size of the data in the specified format or kFormatLengthUnknown (-1) which signifies that the size is unknown. You should continue to read the format until there is no more data. Be aware that the EditionHasFormat function may return kFormatLengthUnknown for the length of the format. Result codes noErr 0 No error noTypeErr Format not available editionMgrInitErr -450 Manager not init’ed æKY ReadEdition æFc Editions.h æT Function æTN A82D æD pascal OSErr ReadEdition(EditionRefNum whichEdition,FormatType whichFormat, Ptr buffPtr,Size *buffLen) = {0x303C,0x081A,0xA82D}; æDT OSErr myVariable = ReadEdition((EditionRefNum) whichEdition,(FormatType) whichFormat,() Ptr buffPtr,(Size *) buffLen); æC Use the ReadEdition function to read data from an edition. The whichEdition parameter is the reference number for the edition. The whichFormat parameter indicates the format type that you want to read. The buffPtr parameter is a pointer to the buffer into which you are reading the edition from. The buffLen parameter is the number of bytes that you want to read into the buffer. The buffLen parameter is also a return value that returns the total number of bytes read into the buffer. Once the buffLen field returns a value less than the value you have specified, there is no additional data to read, and the ReadEdition function returns noErr. If use the ReadEdition function after all data is read in, the ReadEdition function returns an EoFErr. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed noTypeErr Format not available rfNumErr Bad refNum EofErr æKY WriteEdition æFc Editions.h æT Function æTN A82D æD pascal OSErr WriteEdition(EditionRefNum whichEdition,FormatType whichFormat, Ptr buffPtr,Size buffLen) = {0x303C,0x081C,0xA82D}; æDT OSErr myVariable = WriteEdition((EditionRefNum) whichEdition,(FormatType) whichFormat,() Ptr buffPtr,(Size) buffLen); æC Use the WriteEdition function to write data to an edition. The refnum parameter is the reference number for edition. The whichFormat parameter indicates the format type that you want to write. The buffPtr parameter is a pointer to the buffer that you are writing into the edition. The buffLen parameter is the number of bytes that you are writing. If data cannot be entirely written to the edition, the WriteEdition function returns a error. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed noTypeErr Unknown format rfNumErr Bad refNum æKY GetEditionFormatMark æFc Editions.h æT Function æTN A82D æD pascal OSErr GetEditionFormatMark(EditionRefNum whichEdition,FormatType whichFormat, long *currentMark) = {0x303C,0x061E,0xA82D}; æDT OSErr myVariable = GetEditionFormatMark((EditionRefNum) whichEdition,(FormatType) whichFormat,( long) * currentMark); æC Use the GetEditionFormatMark to locate the current marker for a particular format. The whichEdition parameter is the reference number for the edition. The whichFormat parameter indicates the format type for the edition and the currentMark parameter is the offset for the format. If you do not support the format that you are specifying, you receive noTypeErr. Result codes noErr 0 No error noTypeErr Unknown format posErr Mark not set anywhere æKY SetEditionFormatMark æFc Editions.h æT Function æTN A82D æD pascal OSErr SetEditionFormatMark(EditionRefNum whichEdition,FormatType whichFormat, long setMarkTo) = {0x303C,0x0620,0xA82D}; æDT OSErr myVariable = SetEditionFormatMark((EditionRefNum) whichEdition,(FormatType) whichFormat,() long setMarkTo); æC Use the SetEditionFormatMark to set the current mark for a section format. The whichEdition parameter is the reference number for the edition. The whichFormat parameter indicates the format type for the edition and the setMarkTo parameter is the offset for the format. When you are creating a publisher, and if the whichFormat does not exist for a particular edition that you are writing data to, the SetEditionFormatMark creates the format. You need to call the SetEditionFormatMark function before writing data. Result codes noErr 0 No error posErr Manager not init’ed ??? SetHandleSize errors æKY GetEditionInfo æFc Editions.h æT Function æTN A82D æD pascal OSErr GetEditionInfo(const SectionHandle sectionH,EditionInfoRecord *editionInfo) = {0x303C,0x0422,0xA82D}; æDT OSErr myVariable = GetEditionInfo((const SectionHandle) sectionH,(EditionInfoRecord *) editionInfo); æC When the user wants to locate the publisher for a particular subscriber (by choosing Find Publisher in the subscriber options dialog box), use the GetEditionInfo function to find the edition container. You should then call the GotoPublisherSection function. The GetEditionInfo function returns information about a section’s edition such as it’s location, last modification date, creator and type. This function only works for registered sections which contain a non-NIL control block. The sectionH parameter is a handle to the section record for a given section. The editionInfo parameter is a pointer from the EditionInfo record. The GetEditionInfo function comprises the public information contained in the control block. The Edition Manager syncs to ensure that the existing edition name corresponds to the Finder’s existing edition name. Refer to “Reading and Writing Edition Data” for additional information. If an edition container could not be located previously, the GetEditionInfo function tries to locate it again. If it cannot be located a second time, the GetEditionInfo function returns a file not found err. TYPE EditionInfoRecord = RECORD crDate: TimeStamp; mdDate: TimeStamp; fdCreator: OSType; fdType: OSType; container: EditionContainerSpec; END; The fdType field is the creator type 'publ'. The fdCreator field is specified in the OpenNewEdition function. The container field is a volume, folder, and file name for the edition. The crDate field contains the creation date of the edition. The mdDate field contains the modification date of the edition. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed fnfErr Not registered or file moved ??? PBHGetFInfo æKY GotoPublisherSection æFc Editions.h æT Function æTN A82D æD pascal OSErr GotoPublisherSection(const EditionContainerSpec *container) = {0x303C,0x0224,0xA82D}; æDT OSErr myVariable = GotoPublisherSection((const EditionContainerSpec *) container); æC Use the GotoPublisherSection function to resolve the alias in the edition to find the document containing its publisher. This function opens the document, launches it’s application if necessary, and scrolls to the location of the publisher. The container parameter is the edition volume, folder, and file name. You obtain the container by calling the GetEditionInfo function. You should call the GotoPublisherSection function when the user selects Find Publisher within the publisher options dialog box. The action code 'goto' is returned to you. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed badSubPartErr -454 Invalid container MemError NewHandle errors ??? ResolveAlias errors æKY GetLastEditionContainerUsed æFc Editions.h æT Function æTN A82D æD pascal OSErr GetLastEditionContainerUsed(const EditionContainerSpec *container) = {0x303C,0x0226,0xA82D}; æDT OSErr myVariable = GetLastEditionContainerUsed((const EditionContainerSpec *) container); æC The Edition Manager supports three dialog boxes: new publisher and new subscriber dialog boxes and an options dialog box. Your application can display “simple” dialog boxes which require reply records, or you can customize your dialog boxes. Use the GetLastEditionContainerUsed function to display the last edition within the dialog boxes. This function enables a user to easily subscribe to the data recently published. If the GetLastEditionContainer function locates the last edition for which a section was created, the container parameter contains its volume, folder, file name, part, and returns noErr. (The last edition created is associated with the last time that you used the NewSection function.) If the last edition created to is moved or deleted, the GetLastEditionContainer function cannot locate the last edition. The container parameter returns the volume and folder for the edition, leaves the file name blank, and returns fnfErr. The Edition Manager syncs to ensure that its existing edition name corresponds to the Finder’s existing edition name. Refer to “Reading and Writing Edition Data” for additional information. Pass the information from the GetLastEditionContainerUsed function to the NewSubscriberDialog and the NewPublisherDialog functions. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed fnfErr Container not found æKY GetStandardFormats æFc Editions.h æT Function æTN A82D æD pascal OSErr GetStandardFormats(const EditionContainerSpec *container,FormatType *previewFormat, Handle preview,Handle publisherAliss,Handle formats) = {0x303C,0x0A28,0xA82D}; æDT OSErr myVariable = GetStandardFormats((const EditionContainerSpec *) container,(FormatType *) previewFormat,() Handle preview,(Handle) publisherAliss,(Handle) formats); æC This function is called by the Edition Manager to get the alias used in the GotoPublisherSection function and to get the preview shown in the new subscriber dialog box. You will probably not need to call this function directly. The container parameter is a pointer to the edition volume, folder, file name and part. You should pass in valid handes for the formats that you want and NIL for the formats that you don’t want. The handles are resized to the size of the data. The handle fmts reads the virtual format kFormatListFormat, the handle alis reads the format kPublisherDocAliasFormat and the handle prvw tries to find the following formats in this order: prvw, PICT and then TEXT. The first format located returns in the preview handle and the previewFormat parameter is set to its type. If none of the requested formats can be found, noTypeErr is returned. Result codes noErr 0 No error editionMgrInitErr -450 Manager not init’ed noTypeErr Container not found MemError SetHandleSize errors ??? ResolveAlias errors æKY GetEditionOpenerProc æFc Editions.h æT Function æTN A82D æD pascal OSErr GetEditionOpenerProc(EditionOpenerProcPtr *opener) = {0x303C,0x022A,0xA82D}; æDT OSErr myVariable = GetEditionOpenerProc((EditionOpenerProcPtr *) opener); æC Use the GetEditionOpenerProc to locate the current edition opener procedure. The opener procedure returns the pointer to the current edition opener procedure. The PB parameter of the CallFormatIOProc function is a FormatIOParamBlock record. TYPE FormatIOParamBlock = RECORD ioRefNum: LongInt; {} format: FormatType; {} formatIndex: LongInt; {} offset: LongInt; {} buffPtr: Ptr; {} buffLen: LongInt; {} END; The routine parameter is a pointer to a format I/O procedure. You should have an IO function that contains the following parameters. FUNCTION IO (selector: FormatIOVerb; VAR PB: FormatIOParamBlock) : OSErr; æKY SetEditionOpenerProc æFc Editions.h æT Function æTN A82D æD pascal OSErr SetEditionOpenerProc(EditionOpenerProcPtr opener) = {0x303C,0x022C,0xA82D}; æDT OSErr myVariable = SetEditionOpenerProc((EditionOpenerProcPtr) opener); æC Use the SetEditionOpenProc to provide your own edition opener procedure. The opener parameter is a pointer to the edition opener procedure that you are providing. æKY CallEditionOpenerProc æFc Editions.h æT Function æTN A82D æD pascal OSErr CallEditionOpenerProc(EditionOpenerVerb selector,EditionOpenerParamBlock *PB, EditionOpenerProcPtr routine) = {0x303C,0x052E,0xA82D}; æDT OSErr myVariable = CallEditionOpenerProc((EditionOpenerVerb) selector,(EditionOpenerParamBlock *) PB,() EditionOpenerProcPtr routine); æC The Edition Manager never opens or closes an edition container directly—it calls the current “EditionOpener.” Use the CallEditionOpenerProc to call the edition opener procedure pointer. Set the selector parameter to one of the edition opener verbs (eoOpen, eoClose, eoOpenNew, eoCloseNew, eoCanSubscribe). The params parameter is an EditionOpenerParamBlock record. TYPE EditionOpenerParamBlock = RECORD info: EditionInfoRecord; {} sectionH: SectionHandle; {} document: CanonicalFileSpecPtr; {} misc: LongInt; {} ioRefNum: LongInt; {} ioProc: FormatIOProcPtr; {} END; The routine parameter is a pointer to an edition opener procedure. æKY CallFormatIOProc æFc Editions.h æT Function æTN A82D æD pascal OSErr CallFormatIOProc(FormatIOVerb selector,FormatIOParamBlock *PB, FormatIOProcPtr routine) = {0x303C,0x0530,0xA82D}; æDT OSErr myVariable = CallFormatIOProc((FormatIOVerb) selector,(FormatIOParamBlock *) PB,() FormatIOProcPtr routine); æC æKY NewSubscriberDialog æFc Editions.h æT Function æTN A82D æD pascal OSErr NewSubscriberDialog(NewSubscriberReply *reply) = {0x303C,0x0232,0xA82D}; æDT OSErr myVariable = NewSubscriberDialog((NewSubscriberReply *) reply); æC Use the NewSubscriberDialog function to display the new subscriber dialog box on the user’s screen. FUNCTION NewSubscriberDialog (VAR reply: NewSubscriberReply) : OSErr; The reply parameter is the NewSubscriberReply record. TYPE NewSubscriberReply = RECORD canceled: Boolean; {out} container: EditionContainerSpec; {in/out} END; Set the container parameter to be a pointer to a volume, folder, file name, and part for the last edition subscribed to. Upon return of the NewSubscriberDialog function, if the canceled parameter is set to TRUE, the user canceled the dialog box. Otherwise, this parameter is FALSE and the container parameter holds the container for the new subscriber. Result codes noErr 0 No error editionMgrInitErr -450 Package not init’ed badSubPartErr -454 Bad container spec MemError NewHandle errors ResError GetResource errors æKY NewSubscriberExpDialog æFc Editions.h æT Function æTN A82D æD pascal OSErr NewSubscriberExpDialog(NewSubscriberReply *reply,Point where, Short expansionDITLresID,ExpDlgHookProcPtr dlgHook,ExpModalFilterProcPtr filterProc, Ptr yourDataPtr) = {0x303C,0x0B34,0xA82D}; æDT OSErr myVariable = NewSubscriberExpDialog((NewSubscriberReply *) reply,(Point) where,() Short expansionDITLresID,(ExpDlgHookProcPtr) dlgHook,(ExpModalFilterProcPtr) filterProc,() Ptr yourDataPtr); æC Use the NewSubscriberExpDialog function to customize the new subscriber dialog box. The NewSubscriberExpDialog, NewPublisherExpDialog, and SectionOptionsExpDialog functions share the same parameters. Refer below for a detailed explanation of the parameters. Result codes noErr 0 No error editionMgrInitErr -450 Package not init’ed MemError NewHandle errors ResError GetResource errors æKY NewPublisherDialog æFc Editions.h æT Function æTN A82D æD pascal OSErr NewPublisherDialog(NewSubscriberReply *reply) = {0x303C,0x0236,0xA82D}; æDT OSErr myVariable = NewPublisherDialog((NewSubscriberReply *) reply); æC Use the NewPublisherDialog function to display the new publisher dialog box on the user’s screen. The reply parameter is a pointer from the NewPublisherReply record. TYPE NewPublisherReply = RECORD canceled: Boolean; {out} replacing: Boolean; {out} usePart: Boolean; {in} preview: Handle; {in} previewFormat: FormatType; {in} container: EditionContainerSpec {in/out} END; The usePart parameter must be set to FALSE before calling the NewPublisherDialog routine. Set the container parameter to be a pointer to a volume, folder, and file name for a default edition. Set the preview parameter to be a handle to the format for the default edition and set the previewFormat parameter to indicate the format of the default edition. Upon return of the NewPublisherDialog function, the following three output parameters can be set. If the canceled parameter is set to TRUE, the user canceled the dialog box. If the replacing parameter is TRUE, the user chose an existing file name from the list of available editions and confirmed this replacement. If the replacing parameter is TRUE, do not call the CreateEditionContainerFile function which creates a new edition container. The container parameter contains the volume, folder and file name for the default edition. Deallocate the preview parameter to free up memory. Result codes noErr 0 No error editionMgrInitErr -450 Package not init’ed badSubPartErr -454 Bad container spec MemError NewHandle errors ResError GetResource errors æKY NewPublisherExpDialog æFc Editions.h æT Function æTN A82D æD pascal OSErr NewPublisherExpDialog(NewSubscriberReply *reply,Point where, Short expansionDITLresID,ExpDlgHookProcPtr dlgHook,ExpModalFilterProcPtr filterProc, Ptr yourDataPtr) = {0x303C,0x0B38,0xA82D}; æDT OSErr myVariable = NewPublisherExpDialog((NewSubscriberReply *) reply,(Point) where,() Short expansionDITLresID,(ExpDlgHookProcPtr) dlgHook,(ExpModalFilterProcPtr) filterProc,() Ptr yourDataPtr); æC Use the NewPublisherExpDialog function to customize the new publisher dialog box. The NewSubscriberExpDialog, NewPublisherExpDialog, and SectionOptionsExpDialog functions share the same parameters. Refer below for a detailed explanation of the parameters. Result codes noErr 0 No error editionMgrInitErr -450 Package not init’ed MemError NewHandle errors ResError GetResource errors æKY SectionOptionsDialog æFc Editions.h æT Function æTN A82D æD pascal OSErr SectionOptionsDialog(SectionOptionsReply *reply) = {0x303C,0x023A,0xA82D}; æDT OSErr myVariable = SectionOptionsDialog((SectionOptionsReply *) reply); æC Use the SectionOptionsDialog function to display the publisher options and subscriber options dialog boxes on the user’s screen. The reply parameter is a pointer from the SectionOptionsReply record. TYPE SectionOptionsReply = RECORD canceled: Boolean; {out} changed: Boolean; {out} sectionH: SectionHandle; {in} action: ResType; {out} END; The sectionH parameter is a handle to the section record for a given section. Upon return of the SectionOptionsDialog function, the following output parameters can be set. If the canceled parameter is set to TRUE, the user canceled the dialog box. Otherwise, this parameter is FALSE. If the changed parameter is TRUE (if for example, the update mode is changed), the user changed the section record. The action parameter contains the code for 1 of 4 user actions. • action code is 'read' for user selection of Get Edition Now • action code is 'writ' for user selection of Publish Now • action code is 'goto' for user selection of Find Publisher • action code is 'cncl' for user selection of Cancel Publisher or Cancel Subscriber Your application can expand dialog boxes to include DITL items, apply alternate mapping of events to item hits, and apply alternate meanings to the item hits. æKY SectionOptionsExpDialog æFc Editions.h æT Function æTN A82D æD pascal OSErr SectionOptionsExpDialog(SectionOptionsReply *reply,Point where, Short expansionDITLresID,ExpDlgHookProcPtr dlgHook,ExpModalFilterProcPtr filterProc, Ptr yourDataPtr) = {0x303C,0x0B3C,0xA82D}; æDT OSErr myVariable = SectionOptionsExpDialog((SectionOptionsReply *) reply,(Point) where,() Short expansionDITLresID,(ExpDlgHookProcPtr) dlgHook,(ExpModalFilterProcPtr) filterProc,() Ptr yourDataPtr); æC Use the SectionOptionsExpDialog function to customize the publisher and subscriber dialog boxes. The NewSubscriberExpDialog, NewPublisherExpDialog, and SectionOptionsExpDialog functions share the same parameters. Refer below for a detailed explanation of the parameters. Result codes noErr 0 No error editionMgrInitErr -450 Package not init’ed MemError NewHandle errors ResError GetResource errors The reply parameter is a pointer from the NewSubscriberReply, NewPublisherReply, or the SectionOptionsReply records. You can automatically center the dialog box by passing <-1, -1> in the where field. The expansionDITLresID field should be zero or a valid dialog item list (DITL) resource ID. This integer is the ID of a DITL whose items are appended to the end of the standard dialog DITL. The DITL items keep their relative positions, but when they are moved, they move as a group to the bottom of the dialog box. For international purposes, the location of the DITL items is not always the bottom of the dialog box. The location can be specified by a user item in the main DITL. For different script systems, you should arrange your expansionDITL items appropriately. Refer to the Dialog Manager chapter for additional information on DITL. The filterProc parameter should be a valid ExpModalFilterProcPtr or NIL. This procedure is called by the dialog box filterProc. This function enables you to map real events (mouse-down or up or key-down or up) to a hit on an item (such as a cancel button). Each item corresponds to a number. You may want to map a command-key equivalent to an item hit . The dlgHook parameter should be a valid ExpDlgHookProcPtr or NIL. This procedure is called with each call to a dialog box. The dlgHook parameter makes the appropriate action such as filling in a check box with an ‘X’ if this particular item is selected by the user. The itemOffset passed to the procedure is the number of items in the dialog item list befoe the expansionDITL items. You need to subtract itemOffset from item to get the relative item number in the expanstionDITL. The return value from dlgHook is the absolute item number. Some special values for item are: kFirstHookCall (-1), kNullHookCall (100), and kRebuildFileList (101). The callBackPtr parameter is reserved for your use. æKY EPPC.h æKL AcceptHighLevelEvent GetPortNameFromProcessSerialNumber GetProcessSerialNumberFromPortName GetSpecificHighLevelEvent PostHighLevelEvent bufferIsSmall connectionInValid GetSpecificFilterProcPtr HighLevelEventMsg HighLevelEventMsgClass HighLevelEventMsgHdl HighLevelEventMsgPtr kHighLevelEvent msgWasFullyAccepted msgWasNotAccepted msgWasPartiallyAccepted nAttnMsg noOutstandingHLE nReturnReceipt priorityMask receiverIDisPSN receiverIDisSessionID receiverIDisSignature receiverIDisTargetID receiverIDMask registerOnNetwork rtrnReciptMsgID systemOptionsMask TargetID TargetIDPtr æKY kHighLevelEvent æFc EPPC.h æT #define æD #define kHighLevelEvent 23 æC æKY receiverIDMask æFc EPPC.h æT #define æD /* postOptions currently supported */ #define receiverIDMask 0x0000F000 æC æKY receiverIDisPSN æFc EPPC.h æT #define æD #define receiverIDisPSN 0x00008000 æC æKY receiverIDisSignature æFc EPPC.h æT #define æD #define receiverIDisSignature 0x00007000 æC æKY receiverIDisSessionID æFc EPPC.h æT #define æD #define receiverIDisSessionID 0x00006000 æC æKY receiverIDisTargetID æFc EPPC.h æT #define æD #define receiverIDisTargetID 0x00005000 æC æKY systemOptionsMask æFc EPPC.h æT #define æD #define systemOptionsMask 0x00000F00 æC æKY nReturnReceipt æFc EPPC.h æT #define æD #define nReturnReceipt 0x00000200 æC æKY priorityMask æFc EPPC.h æT #define æD #define priorityMask 0x000000FF æC æKY nAttnMsg æFc EPPC.h æT #define æD #define nAttnMsg 0x00000001 æC æKY registerOnNetwork æFc EPPC.h æT #define æD #define registerOnNetwork 0x80000000 æC æKY bufferIsSmall æFc EPPC.h æT #define æD /* error returns from Post and Accept */ */ #define bufferIsSmall -607 æC æKY noOutstandingHLE æFc EPPC.h æT #define æD #define noOutstandingHLE -608 æC æKY connectionInValid æFc EPPC.h æT #define æD #define connectionInValid -609 æC æKY HighLevelEventMsgClass æFc EPPC.h æT #define æD /* constant for return receipts */ */ #define HighLevelEventMsgClass 'jaym' æC æKY rtrnReciptMsgID æFc EPPC.h æT #define æD #define rtrnReciptMsgID 'rtrn' æC æKY msgWasPartiallyAccepted æFc EPPC.h æT #define æD #define msgWasPartiallyAccepted 2 æC æKY msgWasFullyAccepted æFc EPPC.h æT #define æD #define msgWasFullyAccepted 1 æC æKY msgWasNotAccepted æFc EPPC.h æT #define æD #define msgWasNotAccepted 0 æC æKY GetSpecificFilterProcPtr æFc EPPC.h æT typedef æD typedef pascal Boolean (*GetSpecificFilterProcPtr) (unsigned long *param, HighLevelEventMsgPtr msgBuff, TargetID *sender); æC æKY TargetID TargetIDPtr æFc EPPC.h æT struct æD struct TargetID { long sessionID; PortName name; LocName location; PortName recvrName; }; typedef struct TargetID TargetID; typedef TargetID *TargetIDPtr; typedef struct TargetID SenderID, *SenderIDPtr; æC æKY HighLevelEventMsg HighLevelEventMsgPtr HighLevelEventMsgHdl æFc EPPC.h æT struct æD struct HighLevelEventMsg { long sessionID; unsigned short HighLevelEventMsgHeaderLength; unsigned short version; unsigned long reserved1; EventRecord theMsgEvent; unsigned long userRefcon; unsigned long postingOptions; unsigned long msgLength; }; typedef struct HighLevelEventMsg HighLevelEventMsg; typedef HighLevelEventMsg *HighLevelEventMsgPtr, **HighLevelEventMsgHdl; æC æKY PostHighLevelEvent æFc EPPC.h æT Function æTN A88F æD pascal OSErr PostHighLevelEvent(EventRecord *theEvent,unsigned long receiverID, unsigned long msgRefcon,Ptr msgBuff,unsigned long msgLen,unsigned long postingOptions) = {0x3F3C,0x0034,0xA88F}; æDT OSErr myVariable = PostHighLevelEvent((EventRecord *) theEvent,(unsigned long) receiverID,( unsigned) long msgRefcon,(Ptr) msgBuff,(unsigned long) msgLen,(unsigned long) postingOptions); æC You can use the PostHighLevelEvent routine to send a high-level event to another application. You specify the event to send in parameter theEvent, and include any additional data for the event by providing a pointer to a data buffer in the msgBuff parameter. The msgLen parameter specifies the size of the data buffer. The receiverID parameter specifies the recipient of the event. The msgRefcon parameter specifies a unique number associated with this event. Your application can set this field to any value it chooses. You can specify the receiver of the event by session ID, process serial number, signature, or port name and port location. You can use any of these specifications to send an event to another application on the local machine. You can use only the session ID or port name and port location to send an event to an application on a remote machine. You use the postingOptions parameter to specify delivery options and options associated with the receiverID parameter. You can specify one or more delivery options to indicate whether you want the other application to receive the event at the next opportunity, and to indicate whether you want acknowledgment that the event was received by the other application. You use the options associated with the receiverID parameter to indicate how you are specifying the recipient of the event. Result codes noErr 0 Mo error connectionInValid –609 Connection is invalid æKY AcceptHighLevelEvent æFc EPPC.h æT Function æTN A88F æD pascal OSErr AcceptHighLevelEvent(TargetID *sender,unsigned long *msgRefcon, Ptr msgBuff,unsigned long *msgLen) = {0x3F3C,0x0033,0xA88F}; æDT OSErr myVariable = AcceptHighLevelEvent((TargetID *) sender,(unsigned long *) msgRefcon,() Ptr msgBuff,(unsigned long *) msgLen); æC Some high-level events may be fully specified by their event record only, while others may include additional information in an optional buffer. To get any additional information and to find the sender of the event, use the AcceptHighLevelEvent function. The sender of the event is specified in the sender parameter, which is a pointer to a TargetID data structure. The sender parameter contains the session reference number that identifes this communication and the port name and port location of the sender. The msgRefcon parameter is a unique number that is used to identify this event. If you send a response to this event, you should specify the same value of msgRefcon so that the sender of the event can associate the reply with the original request. The msgBuff parameter points to any additional data associated with the event. The msgLen parameter contains the size of the buffer. Your application is responsible for allocating the memory for the additional data pointed to by the msgBuff parameter. If the msgBuff parameter points to an area in memory that is not large enough to hold all the data associated with the event, AcceptHighLevelEvent returns the result code bufferIsSmall. If AcceptHighLevelEvent returns the result code bufferIsSmall, the msgLen parameter contains the number of bytes remaining. You can call AcceptHighLevelEvent again to receive the rest of the data. Result codes noErr 0 No error bufferIsSmall –607 Buffer is too small noOutstandingHLE –608 No outstanding high-level event æKY GetProcessSerialNumberFromPortName æFc EPPC.h æT Function æTN A88F æD pascal OSErr GetProcessSerialNumberFromPortName(PortNamePtr portName,ProcessSerialNumberPtr pPSN) = {0x3F3C,0x0035,0xA88F}; æDT OSErr myVariable = GetProcessSerialNumberFromPortName((PortNamePtr) portName,(ProcessSerialNumberPtr) pPSN); æC æKY GetPortNameFromProcessSerialNumber æFc EPPC.h æT Function æTN A88F æD pascal OSErr GetPortNameFromProcessSerialNumber(PortNamePtr portName,ProcessSerialNumberPtr pPSN) = {0x3F3C,0x0046,0xA88F}; æDT OSErr myVariable = GetPortNameFromProcessSerialNumber((PortNamePtr) portName,(ProcessSerialNumberPtr) pPSN); æC æKY GetSpecificHighLevelEvent æFc EPPC.h æT Function æTN A88F æD pascal Boolean GetSpecificHighLevelEvent(GetSpecificFilterProcPtr aFilter, unsigned long *params,OSErr *err) = {0x3F3C,0x0045,0xA88F}; æDT Boolean myVariable = GetSpecificHighLevelEvent((GetSpecificFilterProcPtr) aFilter,( unsigned long) * params,(OSErr *) err); æC You can use the GetSpecificHighLevelEvent function to select and optionally retrieve a specific high-level event from the high-level event queue. You specify your filter function in the aFilter parameter. GetSpecificHighLevelEvent calls your filter function once for each event on the high-level event queue until your filter function returns TRUE or the end of the queue is reached. You use the params parameter to specify the criteria your filter function should use to select a specific event. For example, you can specify the params parameter as a msgRefcon value to search for a particular event or as a pointer to a targetID structure to search for a specific sender of an event. Or you can search for a specific class of event. Here’s how you declare the filter function aFilter: FUNCTION aFilter (VAR params: LongInt; msgBuff: HighLevelEventMsgPtr; sender: TargetID) : Boolean; The params parameter indicates the criteria your filter function should use to search for a specific event. The msgBuff parameter contains a pointer to a record of type HighLevelEventMsg, which provides information about the event: the event record for the high-level event, the posting options of the event, and so forth. The sender parameter contains the target ID of the application that sent the event. Your filter function can compare the contents of the params parameter with the contents of the msgBuff or senderID parameters. If your filter function finds a match, your filter function should return TRUE. If it does not find a match, your filter function should return FALSE. æKY ErrMgr.h æKL AddErrInsert addInserts CloseErrMgr GetSysErrText GetToolErrText InitErrMgr æKY AddErrInsert æFc ErrMgr.h æT Function æD void AddErrInsert(unsigned char *insert,unsigned char *msgString); æDT AddErrInsert((unsigned char *)insert,(unsigned char *)msgString); æC /* Add another insert to an error message string.This call is used when more than one insert is to be added to a message (because it contains more than one '^' character). */ æKY addInserts æFc ErrMgr.h æT Function æD unsigned char *addInserts(unsigned char *msgString,unsigned char *insert, ...); æDT unsigned char myVariable = addInserts((unsigned char *)msgString,(unsigned char *)insert, (...)); æC /* Add a set of inserts to an error message string. AddErrInsert is called for each insert parameter specified. */ æKY CloseErrMgr æFc ErrMgr.h æT Function æD void CloseErrMgr(void); æDT CloseErrMgr(); æC /* Ideally a CloseErrMgr should be done at the end of execution to make sure all files opened by the ErrMgr are closed. You can let normal program termination do the closing. But if you are a purist... */ æKY GetSysErrText æFc ErrMgr.h æT Function æD char *GetSysErrText(short msgNbr,char *errMsg); æDT char myVariable = GetSysErrText((short)msgNbr,(char *)errMsg); æC /* Get the error message text corresponding to system error number errNbr from the system error message file (whose name was specified in the InitErrMgr call). The text of the message is returned in errMsg and the function returns a pointer to errMsg. The maximum length of the message is limited to 254 characters. Note, if a system message filename was not specified to InitErrMgr, then the ErrMgr assumes the message file contained in the file "SysErrs.Err". This file is first accessed as "{ShellDirectory}SysErrs.Err" on the assumption that SysErrs.Err is kept in the same directory as the MPW Shell. If the file cannot be opened, then an open is attempted on "SysErrs.Err" in the System Folder. */ æKY GetToolErrText æFc ErrMgr.h æT Function æD char *GetToolErrText(short msgNbr,char *errInsert,char *errMsg); æDT char myVariable = GetToolErrText((short)msgNbr,(char *)errInsert,(char *)errMsg); æC /* Get the error message text corresponding to tool error number errNbr from the tool error message file (whose name was specified in the InitErrMgr call). The text of the message is returned in errMsg and the function returns a pointer to errMsg. The maximum length of the message is limited to 254 characters. If the message is to have an insert, then ErrInsert should be a pointer to it. Otherwise it should be either be a null string or a NULL pointer. Inserts are indicated in error messages by specifying a '^' to indicate where the insert is to be placed. Note, if a tool message filename was not specified to InitErrMgr, then the ErrMgr assumes the message file contained in the data fork of the tool calling the ErrMgr. This name is contained in the Shell variable {Command} and the value of that variable is used to open the error message file. */ æKY InitErrMgr æFc ErrMgr.h æT Function æD void InitErrMgr(char *toolErrFilename,char *sysErrFilename,Boolean showToolErrNbrs); æDT InitErrMgr((char *)toolErrFilename,(char *)sysErrFilename, (Boolean)showToolErrNbrs); æC /* ErrMgr initialization.This must be done before using any other ErrMgr routine. Set showToolErrNbrs to true if you want all tool messages to contain the error number following the message text enclosed in parentheses (e.g., "<msg txt> ([OS] Error <n>)"; system error messages always contain the error number). The toolErrFileName parameter is used to specify the name of a tool-specific error file, and should be the NULL or a null string if not used (or if the tool's data fork is to be used as the error file, see GetToolErrText for futher details). The sysErrFileName parameter is used to specify the name of a system error file, and should normally be the NULL or a null string, which causes the ErrMgr to look in the MPW Shell directory for "SysErrs.Err" (see GetSysErrText). If InitErrMgr is NOT called prior to calling GetSysErrText or GetToolErrText, then those routines, the first time they are called, will call InitErrMgr as InitErrMgr(NULL, NULL, true). The following global may be set to true to allow a C caller to process all strings as Pascal strings:*/ extern Boolean pascalStrings; /* set to true for Pascal strings*//* This should be set PRIOR to calling InitErrMgr. Once set, ALL strings, both those passed to the ErrMgr as filenames and error message inserts, as well as the messages returned by the ErrMgr will be Pascal strings. There is NO guarantee a '\0' byte is at the end of the string. Results are unpredictable if pascalStringsis set false after it has been set true! */ æKY ErrNo.h æFc ErrNo.h æC Synopsis #include <ErrNo.h> extern int errno; extern short MacOSErr; Description Many of the Standard C Library functions can return, in addition to their normal return values, a negative value indicating an error, typically –1. For example, a function returning a character as an int will indicate an error by returning –1, which is not a legitimate ASCII value. (See the Descriptions of individual functions for details.) The external variable errno also provides an error number. Variable errno is not cleared on successful calls, so it should be tested only if the return value indicates an error. The error name appears in brackets following the text in a library function description: for example, “The next attempt to write a nonzero number of bytes will signal an error. [ENOSPC]” Not all possible error numbers are listed for each library function because many errors are possible for most of the calls. Some UNIX operating system error numbers do not apply to Macintosh and are not documented in this manual. Some calls go to the Macintosh ROM and return a value in MacOSErr as well as the value in errno. Table 3-2 is a list of the error numbers and their names as defined in the <ErrNo.h> file. Not all the error numbers listed here will be returned, but they are included in the header file for compatibility. Table 3-2 I/O errors Value Identifier Message Explanation 1 EPERM No permission match An attempt was made to modify a file in some way forbidden except to its creator. 2 ENOENT No such file or directory A file whose filename is specified does not exist, or one of the directories in a pathname does not exist. 3 ENORSRC Resource not found A required resource was not found. This error applies to faccess calls that return tab, font, or print record information. 4 EINTR System service interrupted A requested system call cannot be completed. This error may occur if a request to rename a file is unsuccessful. 5 EIO I/O error Some physical I/O error has occurred. This error may in some cases be signaled on a call following the one to which it actually applies. 6 ENXIO No such device or address I/O on a special file refers to a subdevice that does not exist, or the I/O is beyond the limits of the device. This error may also occur when, for example, no disk is present in a drive. 7 E2BIG Insufficient space for The data to be returned is too large for the space allocated to receive it. 9 EBADF Bad file number Either a file descriptor does not refer to an open file, or a read (or write) request is made to a file that is open only for writing (or reading). 12 ENOMEM Not enough space. The system ran out of memory while the library call was executing. 13 EACCES Permission denied. An attempt was made to access a file in a way forbidden by the protection system. 14 EFAULT Illegal filename. A filename or volume name was too long or otherwise illegal. 15 ENOTBLK Block device required. A non-block file was used when a block device was required. 16 EBUSY Device or resource busy. An attempt was made to mount a volume that was already mounted, or to delete a locked file. 17 EEXIST File exists. An existing file was mentioned in an inappropriate context; for example, open(file, O_CREAT+O_EXCL). 18 EXDEV Cross-device link. A link to a file on another device was attempted. 19 ENODEV No such device. An attempt was made to apply an inappropriate system call to a device; for example, read a write-only device. 20 ENOTDIR Not a directory. An object that is not a directory was specified where a directory is required; for example, in a path prefix. 21 EISDIR Is a directory. An attempt was made to write on a directory. 22 EINVAL Invalid parameter. Some invalid parameter was provided to a library function. 23 ENFILE File table overflow. The system’s table of open files is full, so temporarily a call to open cannot be accepted. 24 EMFILE Too many open files. The system cannot allocate memory to record another open file. 25 ENOTTY Not a typewriter. The specified file isn’t a character file. 26 ETXTBSY Text file busy. An attempt was made to open a file that was already open for writing. 27 EFBIG File too large. The size of a file was larger than the maximum file size. 28 ENOSPC No space left on device. During a write to a file, there is no free space left on the device. 29 ESPIPE Illegal seek. An lseek was issued incorrectly. 30 EROFS Read-only file system. An attempt to modify a file or directory was made on a device mounted for read-only access. 31 EMLINK Too many links. An attempt to delete an open file was made. 33 EDOM Math arg out of domain of func. The argument of a math function is outside the domain of the function. 34 ERANGE Math result not representable. The value of a math function can’t be represented within the machine’s precision. Note Calls that interface to the Macintosh I/O system (such as open, close, read, write, and ioctl) can set the external variable MacOSErr as well as errno on errors. This section documents the errno values. The equivalent Macintosh ROM error-return values set in MacOSErr are documented in the System Error Handler chapter of Inside Macintosh. See also hypot, signal, perror, creat, open, close, read, write, ioctl æKY Errors.h æKL SysError abortErr addRefFailed addResFailed afpAccessDenied afpAuthContinue afpBadUAM afpBadVersNum afpBitmapErr afpCallNotSupported afpCantMove afpCantRename afpDenyConflict afpDirNotEmpty afpDirNotFound afpDiskFull afpEofError afpFileBusy afpFlatVol afpIconTypeError afpItemNotFound afpLockErr afpMiscErr afpNoMoreLocks afpNoServer afpObjectExists afpObjectLocked afpObjectNotFound afpObjectTypeErr afpParmErr afpRangeNotLocked afpRangeOverlap afpServerGoingDown afpSessClosed afpTooManyFilesOpen afpUserNotAuth afpVolLocked aspBadVersNum aspBufTooSmall aspNoAck aspNoMoreSess aspNoServers aspParamErr aspServerBusy aspSessClosed aspSizeErr aspTooMany atpBadRsp atpLenErr badATPSkt badBtSlpErr badBuffNum badChannel badCksmErr badDBtSlp badDCksum badEditionFileErr badFormat badMDBErr badMovErr badSectionErr badSubPartErr badUnitErr bdNamErr breakRecd buf2SmallErr cantStepErr catChangedErr cbNotFound cDevErr ckSumErr clkRdErr clkWrErr closErr cMatchErr cNoMemErr containerAlreadyOpenWrn containerNotFoundWrn controlErr corErr cProtectErr cRangeErr cResErr cTempMemErr dataVerErr dceExtErr ddpLenErr ddpSktErr DiffVolErr dInstErr dirFulErr dirNFErr dRemovErr dsAddressErr dsBadLaunch dsBadPatch dsBadSANEopcode dsBadSlotInt dsBusError dsChkErr dsCoreErr dsFinderErr dsFPErr dsFSErr dsGreeting dsHMenuFindErr dsIllInstErr dsIOCoreErr dsIrqErr dskFulErr dsLineAErr dsLineFErr dsLoadErr dsMBarNFnd dsMemFullErr dsMiscErr dsNoPackErr dsNoPatch dsNoPk1 dsNoPk2 dsNoPk3 dsNoPk4 dsNoPk5 dsNoPk6 dsNoPk7 dsNotThe1 dsOvflowErr dsPrivErr dsReinsert dsStknHeap dsSysErr dsTraceErr dsZeroDivErr dupFNErr editionMgrInitErr envBadVers envNotPresent envVersTooBig eofErr evtNotEnb excessCollsns extFSErr extractErr exUserBreak fBsyErr fidExists fidNotFound firstDskErr fLckdErr fmt1Err fmt2Err fnfErr fnOpnErr fontDecError fontNotDeclared fontSubErr framingErr fsDSIntErr fsRnErr gcrOnMFMErr gfpErr hMenuFindErr hwOverrunErr hwParamErr iIOAbortErr initIWMErr ioErr lapProtErr lastDskErr MacOSErr mapReadErr mBarNFnd memAdrErr memAZErr memBCErr memFullErr memLockedErr memPCErr memPurErr memROZErr memROZWarn memSCErr memWZErr menuPrgErr mFulErr multiplePublisherWrn nbpBuffOvr nbpConfDiff nbpDuplicate nbpNISErr nbpNoConfirm nbpNotFound negZcbFreeErr nilHandleErr nmTypErr noAdrMkErr noBridgeErr noDataArea noDriveErr noDtaMkErr noHardware noMacDskErr noMPPErr noNybErr noRelErr noScrapErr noSendResp NotAFileErr notEnoughHardware notOpenErr notRegisteredSectionErr notThePublisherWrn noTypeErr nsDrvErr nsvErr offLinErr openErr opWrErr paramErr parityErr permErr pixMapTooDeepErr portInUse portNotCf posErr prInitErr prWrErr qErr queueFull rcvrErr readErr readQErr recNotFnd reqAborted reqFailed resAttrErr resFNotFound resNotFound resProblem rfNumErr rgnTooBigErr rmvRefFailed rmvResFailed sdmInitErr sdmJTInitErr sdmPRAMInitErr sdmPriInitErr sdmSRTInitErr sectNFErr seekErr seNoDB shutDownAlert siInitSDTblErr siInitSPTblErr siInitVBLQsErr sktClosedErr slotNumErr smBadBoardId smBadRefId smBadsList smBadsPtrErr smBLFieldBad smBlkMoveErr smBusErrTO smByteLanesErr smCkStatusErr smCodeRevErr smCPUErr smCRCFail smDisDrvrNamErr smDisposePErr smEmptySlot smFHBlockRdErr smFormatErr smGetDrvrNamErr smGetPRErr smInitStatVErr smInitTblErr smLWTstBad smNewPErr smNilsBlockErr smNoBoardId smNoBoardsRsrc smNoDir smNoGoodOpens smNoJmpTbl smNoMoresRsrcs smNosInfoArray smOffsetErr smPRAMInitErr smPriInitErr smRecNotFnd smReservedErr smResrvErr smRevisionErr smSDMInitErr smSelOOBErr smsGetDrvrErr smSlotOOBErr smsPointerNil smSRTInitErr smSRTOvrFlErr smUnExBusErr spdAdjErr statusErr strUserBreak svDisabled svTempDisable swOverrunErr teScrapSizeErr tk0BadErr tmfoErr tmwdoErr tooManyReqs tooManySkts twoSideErr unimpErr unitEmptyErr unitTblFullErr updPixMemErr userBreak userCanceledErr verErr vLckdErr volGoneErr volOffLinErr volOnLinErr vTypErr wPrErr wrgVolTypErr writErr wrPermErr wrUnderrun æKY qErr æFc Errors.h æT #define æD #define qErr -1 /*queue element not found during deletion*/ æC æKY vTypErr æFc Errors.h æT #define æD #define vTypErr -2 /*invalid queue element*/ æC æKY corErr æFc Errors.h æT #define æD #define corErr -3 /*core routine number out of range*/ æC æKY unimpErr æFc Errors.h æT #define æD #define unimpErr -4 /*unimplemented core routine*/ æC æKY seNoDB æFc Errors.h æT #define æD #define seNoDB -8 /*no debugger installed to handle debugger command*/ æC æKY controlErr æFc Errors.h æT #define æD #define controlErr -17 /*I/O System Errors*/ æC æKY statusErr æFc Errors.h æT #define æD #define statusErr -18 /*I/O System Errors*/ æC æKY readErr æFc Errors.h æT #define æD #define readErr -19 /*I/O System Errors*/ æC æKY writErr æFc Errors.h æT #define æD #define writErr -20 /*I/O System Errors*/ æC æKY badUnitErr æFc Errors.h æT #define æD #define badUnitErr -21 /*I/O System Errors*/ æC æKY unitEmptyErr æFc Errors.h æT #define æD #define unitEmptyErr -22 /*I/O System Errors*/ æC æKY openErr æFc Errors.h æT #define æD #define openErr -23 /*I/O System Errors*/ æC æKY closErr æFc Errors.h æT #define æD #define closErr -24 /*I/O System Errors*/ æC æKY dRemovErr æFc Errors.h æT #define æD #define dRemovErr -25 /*tried to remove an open driver*/ æC æKY dInstErr æFc Errors.h æT #define æD #define dInstErr -26 /*DrvrInstall couldn't find driver in resources */ æC æKY abortErr æFc Errors.h æT #define æD #define abortErr -27 /*IO call aborted by KillIO*/ æC æKY iIOAbortErr æFc Errors.h æT #define æD #define iIOAbortErr -27 /*IO abort error (Printing Manager)*/ æC æKY notOpenErr æFc Errors.h æT #define æD #define notOpenErr -28 /*Couldn't rd/wr/ctl/sts cause driver not opened*/ æC æKY dirFulErr æFc Errors.h æT #define æD #define dirFulErr -33 /*Directory full*/ æC æKY dskFulErr æFc Errors.h æT #define æD #define dskFulErr -34 /*disk full*/ æC æKY nsvErr æFc Errors.h æT #define æD #define nsvErr -35 /*no such volume*/ æC æKY ioErr æFc Errors.h æT #define æD #define ioErr -36 /*I/O error (bummers)*/ æC æKY bdNamErr æFc Errors.h æT #define æD #define bdNamErr -37 /*there may be no bad names in the final system!*/ æC æKY fnOpnErr æFc Errors.h æT #define æD #define fnOpnErr -38 /*File not open*/ æC æKY eofErr æFc Errors.h æT #define æD #define eofErr -39 /*End of file*/ æC æKY posErr æFc Errors.h æT #define æD #define posErr -40 /*tried to position to before start of file (r/w)*/ æC æKY mFulErr æFc Errors.h æT #define æD #define mFulErr -41 /*memory full (open) or file won't fit (load)*/ æC æKY tmfoErr æFc Errors.h æT #define æD #define tmfoErr -42 /*too many files open*/ æC æKY fnfErr æFc Errors.h æT #define æD #define fnfErr -43 /*File not found*/ æC æKY wPrErr æFc Errors.h æT #define æD #define wPrErr -44 /*diskette is write protected.*/ æC æKY fLckdErr æFc Errors.h æT #define æD #define fLckdErr -45 /*file is locked*/ æC æKY vLckdErr æFc Errors.h æT #define æD #define vLckdErr -46 /*volume is locked*/ æC æKY fBsyErr æFc Errors.h æT #define æD #define fBsyErr -47 /*File is busy (delete)*/ æC æKY dupFNErr æFc Errors.h æT #define æD #define dupFNErr -48 /*duplicate filename (rename)*/ æC æKY opWrErr æFc Errors.h æT #define æD #define opWrErr -49 /*file already open with with write permission*/ æC æKY paramErr æFc Errors.h æT #define æD #define paramErr -50 /*error in user parameter list*/ æC æKY rfNumErr æFc Errors.h æT #define æD #define rfNumErr -51 /*refnum error*/ æC æKY gfpErr æFc Errors.h æT #define æD #define gfpErr -52 /*get file position error*/ æC æKY volOffLinErr æFc Errors.h æT #define æD #define volOffLinErr -53 /*volume not on line error (was Ejected)*/ æC æKY permErr æFc Errors.h æT #define æD #define permErr -54 /*permissions error (on file open)*/ æC æKY pixMapTooDeepErr æFc Errors.h æT #define æD #define pixMapTooDeepErr -148 æC æKY volOnLinErr æFc Errors.h æT #define æD #define volOnLinErr -55 /*drive volume already on-line at MountVol*/ æC æKY nsDrvErr æFc Errors.h æT #define æD #define nsDrvErr -56 /*no such drive (tried to mount a bad drive num)*/ æC æKY noMacDskErr æFc Errors.h æT #define æD #define noMacDskErr -57 /*not a mac diskette (sig bytes are wrong)*/ æC æKY extFSErr æFc Errors.h æT #define æD #define extFSErr -58 /*volume in question belongs to an external fs*/ æC æKY fsRnErr æFc Errors.h æT #define æD #define fsRnErr -59 /*file system internal error:during rename the old entry was deleted but could not be restored.*/ æC æKY badMDBErr æFc Errors.h æT #define æD #define badMDBErr -60 /*bad master directory block*/ æC æKY wrPermErr æFc Errors.h æT #define æD #define wrPermErr -61 /*write permissions error*/ æC æKY fontDecError æFc Errors.h æT #define æD #define fontDecError -64 /*error during font declaration*/ æC æKY lastDskErr æFc Errors.h æT #define æD #define lastDskErr -64 /*I/O System Errors*/ æC æKY noDriveErr æFc Errors.h æT #define æD #define noDriveErr -64 /*drive not installed*/ æC æKY offLinErr æFc Errors.h æT #define æD #define offLinErr -65 /*r/w requested for an off-line drive*/ æC æKY fontNotDeclared æFc Errors.h æT #define æD #define fontNotDeclared -65 /*font not declared*/ æC æKY noNybErr æFc Errors.h æT #define æD #define noNybErr -66 /*couldn't find 5 nybbles in 200 tries*/ æC æKY fontSubErr æFc Errors.h æT #define æD #define fontSubErr -66 /*font substitution occured*/ æC æKY noAdrMkErr æFc Errors.h æT #define æD #define noAdrMkErr -67 /*couldn't find valid addr mark*/ æC æKY dataVerErr æFc Errors.h æT #define æD #define dataVerErr -68 /*read verify compare failed*/ æC æKY badCksmErr æFc Errors.h æT #define æD #define badCksmErr -69 /*addr mark checksum didn't check*/ æC æKY badBtSlpErr æFc Errors.h æT #define æD #define badBtSlpErr -70 /*bad addr mark bit slip nibbles*/ æC æKY noDtaMkErr æFc Errors.h æT #define æD #define noDtaMkErr -71 /*couldn't find a data mark header*/ æC æKY badDCksum æFc Errors.h æT #define æD #define badDCksum -72 /*bad data mark checksum*/ æC æKY badDBtSlp æFc Errors.h æT #define æD #define badDBtSlp -73 /*bad data mark bit slip nibbles*/ æC æKY wrUnderrun æFc Errors.h æT #define æD #define wrUnderrun -74 /*write underrun occurred*/ æC æKY cantStepErr æFc Errors.h æT #define æD #define cantStepErr -75 /*step handshake failed*/ æC æKY tk0BadErr æFc Errors.h æT #define æD #define tk0BadErr -76 /*track 0 detect doesn't change*/ æC æKY initIWMErr æFc Errors.h æT #define æD #define initIWMErr -77 /*unable to initialize IWM*/ æC æKY twoSideErr æFc Errors.h æT #define æD #define twoSideErr -78 /*tried to read 2nd side on a 1-sided drive*/ æC æKY spdAdjErr æFc Errors.h æT #define æD #define spdAdjErr -79 /*unable to correctly adjust disk speed*/ æC æKY seekErr æFc Errors.h æT #define æD #define seekErr -80 /*track number wrong on address mark*/ æC æKY sectNFErr æFc Errors.h æT #define æD #define sectNFErr -81 /*sector number never found on a track*/ æC æKY fmt1Err æFc Errors.h æT #define æD #define fmt1Err -82 /*can't find sector 0 after track format*/ æC æKY fmt2Err æFc Errors.h æT #define æD #define fmt2Err -83 /*can't get enough sync*/ æC æKY verErr æFc Errors.h æT #define æD #define verErr -84 /*track failed to verify*/ æC æKY firstDskErr æFc Errors.h æT #define æD #define firstDskErr -84 /*I/O System Errors*/ æC æKY clkRdErr æFc Errors.h æT #define æD #define clkRdErr -85 /*unable to read same clock value twice*/ æC æKY clkWrErr æFc Errors.h æT #define æD #define clkWrErr -86 /*time written did not verify*/ æC æKY prWrErr æFc Errors.h æT #define æD #define prWrErr -87 /*parameter ram written didn't read-verify*/ æC æKY prInitErr æFc Errors.h æT #define æD #define prInitErr -88 /*InitUtil found the parameter ram uninitialized*/ æC æKY rcvrErr æFc Errors.h æT #define æD #define rcvrErr -89 /*SCC receiver error (framing; parity; OR)*/ æC æKY breakRecd æFc Errors.h æT #define æD #define breakRecd -90 /*Break received (SCC)*/ æC æKY ddpSktErr æFc Errors.h æT #define æD #define ddpSktErr -91 /*error in soket number*/ æC æKY ddpLenErr æFc Errors.h æT #define æD #define ddpLenErr -92 /*data length too big*/ æC æKY noBridgeErr æFc Errors.h æT #define æD #define noBridgeErr -93 /*no network bridge for non-local send*/ æC æKY lapProtErr æFc Errors.h æT #define æD #define lapProtErr -94 /*error in attaching/detaching protocol*/ æC æKY excessCollsns æFc Errors.h æT #define æD #define excessCollsns -95 /*excessive collisions on write*/ æC æKY portInUse æFc Errors.h æT #define æD #define portInUse -97 /*driver Open error code (port is in use)*/ æC æKY portNotCf æFc Errors.h æT #define æD #define portNotCf -98 /*driver Open error code (parameter RAM not configured for this connection)*/ æC æKY memROZErr æFc Errors.h æT #define æD #define memROZErr -99 /*hard error in ROZ*/ æC æKY noScrapErr æFc Errors.h æT #define æD #define noScrapErr -100 /*No scrap exists error*/ æC æKY noTypeErr æFc Errors.h æT #define æD #define noTypeErr -102 /*No object of that type in scrap*/ æC æKY memFullErr æFc Errors.h æT #define æD #define memFullErr -108 /*Not enough room in heap zone*/ æC æKY nilHandleErr æFc Errors.h æT #define æD #define nilHandleErr -109 /*Master Pointer was NIL in HandleZone or other*/ æC æKY memAdrErr æFc Errors.h æT #define æD #define memAdrErr -110 /*address was odd; or out of range*/ æC æKY memWZErr æFc Errors.h æT #define æD #define memWZErr -111 /*WhichZone failed (applied to free block)*/ æC æKY memPurErr æFc Errors.h æT #define æD #define memPurErr -112 /*trying to purge a locked or non-purgeable block*/ æC æKY memAZErr æFc Errors.h æT #define æD #define memAZErr -113 /*Address in zone check failed*/ æC æKY memPCErr æFc Errors.h æT #define æD #define memPCErr -114 /*Pointer Check failed*/ æC æKY memBCErr æFc Errors.h æT #define æD #define memBCErr -115 /*Block Check failed*/ æC æKY memSCErr æFc Errors.h æT #define æD #define memSCErr -116 /*Size Check failed*/ æC æKY memLockedErr æFc Errors.h æT #define æD #define memLockedErr -117 /*trying to move a locked block (MoveHHi)*/ æC æKY dirNFErr æFc Errors.h æT #define æD #define dirNFErr -120 /*Directory not found*/ æC æKY tmwdoErr æFc Errors.h æT #define æD #define tmwdoErr -121 /*No free WDCB available*/ æC æKY badMovErr æFc Errors.h æT #define æD #define badMovErr -122 /*Move into offspring error*/ æC æKY wrgVolTypErr æFc Errors.h æT #define æD #define wrgVolTypErr -123 /*Wrong volume type error [operation not supported for MFS]*/ æC æKY volGoneErr æFc Errors.h æT #define æD #define volGoneErr -124 /*Server volume has been disconnected.*/ æC æKY fsDSIntErr æFc Errors.h æT #define æD #define fsDSIntErr -127 /*Internal file system error*/ æC æKY userCanceledErr æFc Errors.h æT #define æD #define userCanceledErr -128 æC æKY fidNotFound æFc Errors.h æT #define æD #define fidNotFound -1300 /*no file thread exists.*/ æC æKY fidExists æFc Errors.h æT #define æD #define fidExists -1301 /*file id already exists*/ æC æKY NotAFileErr æFc Errors.h æT #define æD #define NotAFileErr -1302 /*directory specified*/ æC æKY DiffVolErr æFc Errors.h æT #define æD #define DiffVolErr -1303 /*files on different volumes*/ æC æKY catChangedErr æFc Errors.h æT #define æD #define catChangedErr -1304 /*the catalog has been modified*/ æC æKY resNotFound æFc Errors.h æT #define æD #define resNotFound -192 /*Resource not found*/ æC æKY resFNotFound æFc Errors.h æT #define æD #define resFNotFound -193 /*Resource file not found*/ æC æKY addResFailed æFc Errors.h æT #define æD #define addResFailed -194 /*AddResource failed*/ æC æKY addRefFailed æFc Errors.h æT #define æD #define addRefFailed -195 /*AddReference failed*/ æC æKY rmvResFailed æFc Errors.h æT #define æD #define rmvResFailed -196 /*RmveResource failed*/ æC æKY rmvRefFailed æFc Errors.h æT #define æD #define rmvRefFailed -197 /*RmveReference failed*/ æC æKY resAttrErr æFc Errors.h æT #define æD #define resAttrErr -198 /*attribute inconsistent with operation*/ æC æKY mapReadErr æFc Errors.h æT #define æD #define mapReadErr -199 /*map inconsistent with operation*/ æC æKY editionMgrInitErr æFc Errors.h æT #define æD #define editionMgrInitErr -450 /*edition manager not inited by this app*/ æC æKY badSectionErr æFc Errors.h æT #define æD #define badSectionErr -451 /*not a valid SectionRecord*/ æC æKY notRegisteredSectionErr æFc Errors.h æT #define æD #define notRegisteredSectionErr -452 /*not a registered SectionRecord*/ æC æKY badEditionFileErr æFc Errors.h æT #define æD #define badEditionFileErr -453 /*edition file is corrupt*/ æC æKY badSubPartErr æFc Errors.h æT #define æD #define badSubPartErr -454 /*can not use sub parts in this release*/ æC æKY multiplePublisherWrn æFc Errors.h æT #define æD #define multiplePublisherWrn -460 /*A Publisher is already registered for that container*/ æC æKY containerNotFoundWrn æFc Errors.h æT #define æD #define containerNotFoundWrn -461 /*could not find editionContainer at this time*/ æC æKY containerAlreadyOpenWrn æFc Errors.h æT #define æD #define containerAlreadyOpenWrn -462 /*container already opened by this section*/ æC æKY notThePublisherWrn æFc Errors.h æT #define æD #define notThePublisherWrn -463 /*not the first registered publisher for that container*/ æC æKY userBreak æFc Errors.h æT #define æD #define userBreak -490 /*user debugger break*/ æC æKY strUserBreak æFc Errors.h æT #define æD #define strUserBreak -491 /*user debugger break; display string on stack*/ æC æKY exUserBreak æFc Errors.h æT #define æD #define exUserBreak -492 /*user debugger break; execute debugger commands on stack*/ æC æKY nbpBuffOvr æFc Errors.h æT #define æD #define nbpBuffOvr -1024 /*Buffer overflow in LookupName*/ æC æKY nbpNoConfirm æFc Errors.h æT #define æD #define nbpNoConfirm -1025 æC æKY nbpConfDiff æFc Errors.h æT #define æD #define nbpConfDiff -1026 /*Name confirmed at different socket*/ æC æKY nbpDuplicate æFc Errors.h æT #define æD #define nbpDuplicate -1027 /*Duplicate name exists already*/ æC æKY nbpNotFound æFc Errors.h æT #define æD #define nbpNotFound -1028 /*Name not found on remove*/ æC æKY nbpNISErr æFc Errors.h æT #define æD #define nbpNISErr -1029 /*Error trying to open the NIS*/ æC æKY aspBadVersNum æFc Errors.h æT #define æD #define aspBadVersNum -1066 /*Server cannot support this ASP version*/ æC æKY aspBufTooSmall æFc Errors.h æT #define æD #define aspBufTooSmall -1067 /*Buffer too small*/ æC æKY aspNoMoreSess æFc Errors.h æT #define æD #define aspNoMoreSess -1068 /*No more sessions on server*/ æC æKY aspNoServers æFc Errors.h æT #define æD #define aspNoServers -1069 /*No servers at that address*/ æC æKY aspParamErr æFc Errors.h æT #define æD #define aspParamErr -1070 /*Parameter error*/ æC æKY aspServerBusy æFc Errors.h æT #define æD #define aspServerBusy -1071 /*Server cannot open another session*/ æC æKY aspSessClosed æFc Errors.h æT #define æD #define aspSessClosed -1072 /*Session closed*/ æC æKY aspSizeErr æFc Errors.h æT #define æD #define aspSizeErr -1073 /*Command block too big*/ æC æKY aspTooMany æFc Errors.h æT #define æD #define aspTooMany -1074 /*Too many clients (server error)*/ æC æKY aspNoAck æFc Errors.h æT #define æD #define aspNoAck -1075 /*No ack on attention request (server err)*/ æC æKY reqFailed æFc Errors.h æT #define æD #define reqFailed -1096 æC æKY tooManyReqs æFc Errors.h æT #define æD #define tooManyReqs -1097 æC æKY tooManySkts æFc Errors.h æT #define æD #define tooManySkts -1098 æC æKY badATPSkt æFc Errors.h æT #define æD #define badATPSkt -1099 æC æKY badBuffNum æFc Errors.h æT #define æD #define badBuffNum -1100 æC æKY noRelErr æFc Errors.h æT #define æD #define noRelErr -1101 æC æKY cbNotFound æFc Errors.h æT #define æD #define cbNotFound -1102 æC æKY noSendResp æFc Errors.h æT #define æD #define noSendResp -1103 æC æKY noDataArea æFc Errors.h æT #define æD #define noDataArea -1104 æC æKY reqAborted æFc Errors.h æT #define æD #define reqAborted -1105 æC æKY buf2SmallErr æFc Errors.h æT #define æD #define buf2SmallErr -3101 æC æKY noMPPErr æFc Errors.h æT #define æD #define noMPPErr -3102 æC æKY ckSumErr æFc Errors.h æT #define æD #define ckSumErr -3103 æC æKY extractErr æFc Errors.h æT #define æD #define extractErr -3104 æC æKY readQErr æFc Errors.h æT #define æD #define readQErr -3105 æC æKY atpLenErr æFc Errors.h æT #define æD #define atpLenErr -3106 æC æKY atpBadRsp æFc Errors.h æT #define æD #define atpBadRsp -3107 æC æKY recNotFnd æFc Errors.h æT #define æD #define recNotFnd -3108 æC æKY sktClosedErr æFc Errors.h æT #define æD #define sktClosedErr -3109 æC æKY afpAccessDenied æFc Errors.h æT #define æD #define afpAccessDenied -5000 æC æKY afpAuthContinue æFc Errors.h æT #define æD #define afpAuthContinue -5001 æC æKY afpBadUAM æFc Errors.h æT #define æD #define afpBadUAM -5002 æC æKY afpBadVersNum æFc Errors.h æT #define æD #define afpBadVersNum -5003 æC æKY afpBitmapErr æFc Errors.h æT #define æD #define afpBitmapErr -5004 æC æKY afpCantMove æFc Errors.h æT #define æD #define afpCantMove -5005 æC æKY afpDenyConflict æFc Errors.h æT #define æD #define afpDenyConflict -5006 æC æKY afpDirNotEmpty æFc Errors.h æT #define æD #define afpDirNotEmpty -5007 æC æKY afpDiskFull æFc Errors.h æT #define æD #define afpDiskFull -5008 æC æKY afpEofError æFc Errors.h æT #define æD #define afpEofError -5009 æC æKY afpFileBusy æFc Errors.h æT #define æD #define afpFileBusy -5010 æC æKY afpFlatVol æFc Errors.h æT #define æD #define afpFlatVol -5011 æC æKY afpItemNotFound æFc Errors.h æT #define æD #define afpItemNotFound -5012 æC æKY memROZWarn æFc Errors.h æT #define æD #define memROZWarn -99 /*soft error in ROZ*/ æC æKY afpLockErr æFc Errors.h æT #define æD #define afpLockErr -5013 æC æKY afpMiscErr æFc Errors.h æT #define æD #define afpMiscErr -5014 æC æKY afpNoMoreLocks æFc Errors.h æT #define æD #define afpNoMoreLocks -5015 æC æKY afpNoServer æFc Errors.h æT #define æD #define afpNoServer -5016 æC æKY afpObjectExists æFc Errors.h æT #define æD #define afpObjectExists -5017 æC æKY afpObjectNotFound æFc Errors.h æT #define æD #define afpObjectNotFound -5018 æC æKY afpParmErr æFc Errors.h æT #define æD #define afpParmErr -5019 æC æKY afpRangeNotLocked æFc Errors.h æT #define æD #define afpRangeNotLocked -5020 æC æKY afpRangeOverlap æFc Errors.h æT #define æD #define afpRangeOverlap -5021 æC æKY afpSessClosed æFc Errors.h æT #define æD #define afpSessClosed -5022 æC æKY afpUserNotAuth æFc Errors.h æT #define æD #define afpUserNotAuth -5023 æC æKY afpCallNotSupported æFc Errors.h æT #define æD #define afpCallNotSupported -5024 æC æKY afpObjectTypeErr æFc Errors.h æT #define æD #define afpObjectTypeErr -5025 æC æKY afpTooManyFilesOpen æFc Errors.h æT #define æD #define afpTooManyFilesOpen -5026 æC æKY afpServerGoingDown æFc Errors.h æT #define æD #define afpServerGoingDown -5027 æC æKY afpCantRename æFc Errors.h æT #define æD #define afpCantRename -5028 æC æKY afpDirNotFound æFc Errors.h æT #define æD #define afpDirNotFound -5029 æC æKY afpIconTypeError æFc Errors.h æT #define æD #define afpIconTypeError -5030 æC æKY afpVolLocked æFc Errors.h æT #define æD #define afpVolLocked -5031 /*Volume is Read-Only*/ æC æKY afpObjectLocked æFc Errors.h æT #define æD #define afpObjectLocked -5032 /*Object is M/R/D/W inhibited*/ æC æKY envNotPresent æFc Errors.h æT #define æD #define envNotPresent -5500 /*returned by glue.*/ æC æKY envBadVers æFc Errors.h æT #define æD #define envBadVers -5501 /*Version non-positive*/ æC æKY envVersTooBig æFc Errors.h æT #define æD #define envVersTooBig -5502 /*Version bigger than call can handle*/ æC æKY evtNotEnb æFc Errors.h æT #define æD #define evtNotEnb 1 /*event not enabled at PostEvent*/ æC æKY dsSysErr æFc Errors.h æT #define æD #define dsSysErr 32767 /*general system error*/ æC æKY dsBusError æFc Errors.h æT #define æD #define dsBusError 1 /*bus error */ æC æKY dsAddressErr æFc Errors.h æT #define æD #define dsAddressErr 2 /*address error*/ æC æKY dsIllInstErr æFc Errors.h æT #define æD #define dsIllInstErr 3 /*illegal instruction error*/ æC æKY dsZeroDivErr æFc Errors.h æT #define æD #define dsZeroDivErr 4 /*zero divide error*/ æC æKY dsChkErr æFc Errors.h æT #define æD #define dsChkErr 5 /*check trap error*/ æC æKY dsOvflowErr æFc Errors.h æT #define æD #define dsOvflowErr 6 /*overflow trap error*/ æC æKY dsPrivErr æFc Errors.h æT #define æD #define dsPrivErr 7 /*privilege violation error*/ æC æKY dsTraceErr æFc Errors.h æT #define æD #define dsTraceErr 8 /*trace mode error*/ æC æKY dsLineAErr æFc Errors.h æT #define æD #define dsLineAErr 9 /*line 1010 trap error*/ æC æKY dsLineFErr æFc Errors.h æT #define æD #define dsLineFErr 10 /*line 1111 trap error*/ æC æKY dsMiscErr æFc Errors.h æT #define æD #define dsMiscErr 11 /*miscellaneous hardware exception error*/ æC æKY dsCoreErr æFc Errors.h æT #define æD #define dsCoreErr 12 /*unimplemented core routine error*/ æC æKY dsIrqErr æFc Errors.h æT #define æD #define dsIrqErr 13 /*uninstalled interrupt error*/ æC æKY dsIOCoreErr æFc Errors.h æT #define æD #define dsIOCoreErr 14 /*IO Core Error*/ æC æKY dsLoadErr æFc Errors.h æT #define æD #define dsLoadErr 15 /*Segment Loader Error*/ æC æKY dsFPErr æFc Errors.h æT #define æD #define dsFPErr 16 /*Floating point error*/ æC æKY dsNoPackErr æFc Errors.h æT #define æD #define dsNoPackErr 17 /*package 0 not present*/ æC æKY dsNoPk1 æFc Errors.h æT #define æD #define dsNoPk1 18 /*package 1 not present*/ æC æKY dsNoPk2 æFc Errors.h æT #define æD #define dsNoPk2 19 /*package 2 not present*/ æC æKY dsNoPk3 æFc Errors.h æT #define æD #define dsNoPk3 20 /*package 3 not present*/ æC æKY dsNoPk4 æFc Errors.h æT #define æD #define dsNoPk4 21 /*package 4 not present*/ æC æKY dsNoPk5 æFc Errors.h æT #define æD #define dsNoPk5 22 /*package 5 not present*/ æC æKY dsNoPk6 æFc Errors.h æT #define æD #define dsNoPk6 23 /*package 6 not present*/ æC æKY dsNoPk7 æFc Errors.h æT #define æD #define dsNoPk7 24 /*package 7 not present*/ æC æKY dsMemFullErr æFc Errors.h æT #define æD #define dsMemFullErr 25 /*out of memory!*/ æC æKY dsBadLaunch æFc Errors.h æT #define æD #define dsBadLaunch 26 /*can't launch file*/ æC æKY dsFSErr æFc Errors.h æT #define æD #define dsFSErr 27 /*file system map has been trashed*/ æC æKY dsStknHeap æFc Errors.h æT #define æD #define dsStknHeap 28 /*stack has moved into application heap*/ æC æKY dsReinsert æFc Errors.h æT #define æD #define dsReinsert 30 /*request user to reinsert off-line volume*/ æC æKY dsNotThe1 æFc Errors.h æT #define æD #define dsNotThe1 31 /*not the disk I wanted*/ æC æKY negZcbFreeErr æFc Errors.h æT #define æD #define negZcbFreeErr 33 /*ZcbFree has gone negative*/ æC æKY dsGreeting æFc Errors.h æT #define æD #define dsGreeting 40 /*welcome to Macintosh greeting*/ æC æKY dsFinderErr æFc Errors.h æT #define æD #define dsFinderErr 41 /*can't load the Finder error*/ æC æKY shutDownAlert æFc Errors.h æT #define æD #define shutDownAlert 42 /*handled like a shutdown error*/ æC æKY menuPrgErr æFc Errors.h æT #define æD #define menuPrgErr 84 /*happens when a menu is purged*/ æC æKY swOverrunErr æFc Errors.h æT #define æD #define swOverrunErr 1 /*serial driver error masks*/ æC æKY parityErr æFc Errors.h æT #define æD #define parityErr 16 /*serial driver error masks*/ æC æKY hwOverrunErr æFc Errors.h æT #define æD #define hwOverrunErr 32 /*serial driver error masks*/ æC æKY framingErr æFc Errors.h æT #define æD #define framingErr 64 /*serial driver error masks*/ æC æKY cMatchErr æFc Errors.h æT #define æD #define cMatchErr -150 /*Color2Index failed to find an index*/ æC æKY cTempMemErr æFc Errors.h æT #define æD #define cTempMemErr -151 /*failed to allocate memory for temporary structures*/ æC æKY cNoMemErr æFc Errors.h æT #define æD #define cNoMemErr -152 /*failed to allocate memory for structure*/ æC æKY cRangeErr æFc Errors.h æT #define æD #define cRangeErr -153 /*range error on colorTable request*/ æC æKY cProtectErr æFc Errors.h æT #define æD #define cProtectErr -154 /*colorTable entry protection violation*/ æC æKY cDevErr æFc Errors.h æT #define æD #define cDevErr -155 /*invalid type of graphics device*/ æC æKY cResErr æFc Errors.h æT #define æD #define cResErr -156 /*invalid resolution for MakeITable*/ æC æKY unitTblFullErr æFc Errors.h æT #define æD #define unitTblFullErr -29 /*unit table has no more entries*/ æC æKY dceExtErr æFc Errors.h æT #define æD #define dceExtErr -30 /*dce extension error*/ æC æKY dsBadSlotInt æFc Errors.h æT #define æD #define dsBadSlotInt 51 /*unserviceable slot interrupt*/ æC æKY dsBadSANEopcode æFc Errors.h æT #define æD #define dsBadSANEopcode 81 /*bad opcode given to SANE Pack4*/ æC æKY dsNoPatch æFc Errors.h æT #define æD #define dsNoPatch 98 /*Can't patch for particular Model Mac*/ æC æKY dsBadPatch æFc Errors.h æT #define æD #define dsBadPatch 99 /*Can't load patch resource*/ æC æKY updPixMemErr æFc Errors.h æT #define æD #define updPixMemErr -125 /*insufficient memory to update a pixmap*/ æC /*insuffiFc Errors.h CIent memory to update a pixmap*/ æKY mBarNFnd æFc Errors.h æT #define æD #define mBarNFnd -126 /*system error code for MBDF not found*/ æC æKY hMenuFindErr æFc Errors.h æT #define æD #define hMenuFindErr -127 /*could not find HMenu's parent in MenuKey*/ æC æKY noHardware æFc Errors.h æT #define æD #define noHardware -200 /*Sound Manager Error Returns*/ æC æKY notEnoughHardware æFc Errors.h æT #define æD #define notEnoughHardware -201 /*Sound Manager Error Returns*/ æC æKY queueFull æFc Errors.h æT #define æD #define queueFull -203 /*Sound Manager Error Returns*/ æC æKY resProblem æFc Errors.h æT #define æD #define resProblem -204 /*Sound Manager Error Returns*/ æC æKY badChannel æFc Errors.h æT #define æD #define badChannel -205 /*Sound Manager Error Returns*/ æC æKY badFormat æFc Errors.h æT #define æD #define badFormat -206 /*Sound Manager Error Returns*/ æC æKY smSDMInitErr æFc Errors.h æT #define æD #define smSDMInitErr -290 /*Error; SDM could not be initialized.*/ æC æKY smSRTInitErr æFc Errors.h æT #define æD #define smSRTInitErr -291 /*Error; Slot Resource Table could not be initialized.*/ æC æKY smPRAMInitErr æFc Errors.h æT #define æD #define smPRAMInitErr -292 /*Error; Slot Resource Table could not be initialized.*/ æC æKY smPriInitErr æFc Errors.h æT #define æD #define smPriInitErr -293 /*Error; Cards could not be initialized.*/ æC æKY nmTypErr æFc Errors.h æT #define æD #define nmTypErr -299 æC æKY smEmptySlot æFc Errors.h æT #define æD #define smEmptySlot -300 /*No card in slot*/ æC æKY smCRCFail æFc Errors.h æT #define æD #define smCRCFail -301 /*CRC check failed for declaration data*/ æC æKY smFormatErr æFc Errors.h æT #define æD #define smFormatErr -302 /*FHeader Format is not Apple's*/ æC æKY smRevisionErr æFc Errors.h æT #define æD #define smRevisionErr -303 /*Wrong revison level*/ æC æKY smNoDir æFc Errors.h æT #define æD #define smNoDir -304 /*Directory offset is Nil */ æC æKY smLWTstBad æFc Errors.h æT #define æD #define smLWTstBad -305 /*Long Word test field <> $5A932BC7.*/ æC æKY smNosInfoArray æFc Errors.h æT #define æD #define smNosInfoArray -306 /*No sInfoArray. Memory Mgr error.*/ æC æKY smResrvErr æFc Errors.h æT #define æD #define smResrvErr -307 /*Fatal reserved error. Resreved field <> 0.*/ æC æKY smUnExBusErr æFc Errors.h æT #define æD #define smUnExBusErr -308 /*Unexpected BusError*/ æC æKY smBLFieldBad æFc Errors.h æT #define æD #define smBLFieldBad -309 /*ByteLanes field was bad.*/ æC æKY smFHBlockRdErr æFc Errors.h æT #define æD #define smFHBlockRdErr -310 /*Error occured during _sGetFHeader.*/ æC æKY smDisposePErr æFc Errors.h æT #define æD #define smDisposePErr -312 /*_DisposePointer error*/ æC æKY smNoBoardsRsrc æFc Errors.h æT #define æD #define smNoBoardsRsrc -313 /*No Board sResource.*/ æC æKY smGetPRErr æFc Errors.h æT #define æD #define smGetPRErr -314 /*Error occured during _sGetPRAMRec (See SIMStatus).*/ æC æKY smNoBoardId æFc Errors.h æT #define æD #define smNoBoardId -315 /*No Board Id.*/ æC æKY smInitStatVErr æFc Errors.h æT #define æD #define smInitStatVErr -316 /*The InitStatusV field was negative after primary or secondary init.*/ æC æKY smInitTblErr æFc Errors.h æT #define æD #define smInitTblErr -317 /*An error occured while trying to initialize the Slot Resource Table.*/ æC æKY smNoJmpTbl æFc Errors.h æT #define æD #define smNoJmpTbl -318 /*SDM jump table could not be created.*/ æC æKY smBadBoardId æFc Errors.h æT #define æD #define smBadBoardId -319 /*BoardId was wrong; re-init the PRAM record.*/ æC æKY smBusErrTO æFc Errors.h æT #define æD #define smBusErrTO -320 /*BusError time out.*/ æC æKY smBadRefId æFc Errors.h æT #define æD #define smBadRefId -330 /*Reference Id not found in List*/ æC æKY smBadsList æFc Errors.h æT #define æD #define smBadsList -331 /*Bad sList: Id1 < Id2 < Id3 ...format is not followed.*/ æC æKY smReservedErr æFc Errors.h æT #define æD #define smReservedErr -332 /*Reserved field not zero*/ æC æKY smCodeRevErr æFc Errors.h æT #define æD #define smCodeRevErr -333 /*Code revision is wrong*/ æC æKY smCPUErr æFc Errors.h æT #define æD #define smCPUErr -334 /*Code revision is wrong*/ æC æKY smsPointerNil æFc Errors.h æT #define æD #define smsPointerNil -335 /*LPointer is nil From sOffsetData. If this error occurs; check sInfo rec for more information.*/ æC æKY smNilsBlockErr æFc Errors.h æT #define æD #define smNilsBlockErr -336 /*Nil sBlock error (Dont allocate and try to use a nil sBlock)*/ æC æKY smSlotOOBErr æFc Errors.h æT #define æD #define smSlotOOBErr -337 /*Slot out of bounds error*/ æC æKY smSelOOBErr æFc Errors.h æT #define æD #define smSelOOBErr -338 /*Selector out of bounds error*/ æC æKY smNewPErr æFc Errors.h æT #define æD #define smNewPErr -339 /*_NewPtr error*/ æC æKY smBlkMoveErr æFc Errors.h æT #define æD #define smBlkMoveErr -340 /*_BlockMove error*/ æC æKY smCkStatusErr æFc Errors.h æT #define æD #define smCkStatusErr -341 /*Status of slot = fail.*/ æC æKY smGetDrvrNamErr æFc Errors.h æT #define æD #define smGetDrvrNamErr -342 /*Error occured during _sGetDrvrName.*/ æC æKY smDisDrvrNamErr æFc Errors.h æT #define æD #define smDisDrvrNamErr -343 /*Error occured during _sDisDrvrName.*/ æC æKY smNoMoresRsrcs æFc Errors.h æT #define æD #define smNoMoresRsrcs -344 /*No more sResources*/ æC æKY smsGetDrvrErr æFc Errors.h æT #define æD #define smsGetDrvrErr -345 /*Error occurred during _sGetDriver.*/ æC æKY smBadsPtrErr æFc Errors.h æT #define æD #define smBadsPtrErr -346 /*Bad pointer was passed to sCalcsPointer*/ æC æKY smByteLanesErr æFc Errors.h æT #define æD #define smByteLanesErr -347 /*NumByteLanes was determined to be zero.*/ æC æKY smOffsetErr æFc Errors.h æT #define æD #define smOffsetErr -348 /*Offset was too big (temporary error*/ æC æKY smNoGoodOpens æFc Errors.h æT #define æD #define smNoGoodOpens -349 /*No opens were successfull in the loop.*/ æC æKY smSRTOvrFlErr æFc Errors.h æT #define æD #define smSRTOvrFlErr -350 /*SRT over flow.*/ æC æKY smRecNotFnd æFc Errors.h æT #define æD #define smRecNotFnd -351 /*Record not found in the SRT.*/ æC æKY slotNumErr æFc Errors.h æT #define æD #define slotNumErr -360 /*invalid slot # error*/ æC æKY gcrOnMFMErr æFc Errors.h æT #define æD #define gcrOnMFMErr -400 /*gcr format on high density media error*/ æC æKY rgnTooBigErr æFc Errors.h æT #define æD #define rgnTooBigErr -500 æC æKY teScrapSizeErr æFc Errors.h æT #define æD #define teScrapSizeErr -501 /*scrap item too big for text edit record*/ æC æKY hwParamErr æFc Errors.h æT #define æD #define hwParamErr -502 /*bad selector for _HWPriv*/ æC æKY svTempDisable æFc Errors.h æT #define æD /* The following errors are for primary or secondary init code. The errors are logged in the vendor status field of the sInfo record. Normally the vendor error is not Apple's concern, but a special error is needed to patch secondary inits. */ #define svTempDisable -32768 /*Temporarily disable card but run primary init.*/ æC æKY svDisabled æFc Errors.h æT #define æD #define svDisabled -32640 /*Reserve range -32640 to -32768 for Apple temp disables.*/ æC æKY siInitSDTblErr æFc Errors.h æT #define æD #define siInitSDTblErr 1 /*slot int dispatch table could not be initialized.*/ æC æKY siInitVBLQsErr æFc Errors.h æT #define æD #define siInitVBLQsErr 2 /*VBLqueues for all slots could not be initialized.*/ æC æKY siInitSPTblErr æFc Errors.h æT #define æD #define siInitSPTblErr 3 /*slot priority table could not be initialized.*/ æC æKY sdmJTInitErr æFc Errors.h æT #define æD #define sdmJTInitErr 10 /*SDM Jump Table could not be initialized.*/ æC æKY sdmInitErr æFc Errors.h æT #define æD #define sdmInitErr 11 /*SDM could not be initialized.*/ æC æKY sdmSRTInitErr æFc Errors.h æT #define æD #define sdmSRTInitErr 12 /*Slot Resource Table could not be initialized.*/ æC æKY sdmPRAMInitErr æFc Errors.h æT #define æD #define sdmPRAMInitErr 13 /*Slot PRAM could not be initialized.*/ æC æKY sdmPriInitErr æFc Errors.h æT #define æD #define sdmPriInitErr 14 /*Cards could not be initialized.*/ æC æKY dsMBarNFnd æFc Errors.h æT #define æD #define dsMBarNFnd 85 /*Menu Manager Errors*/ æC æKY dsHMenuFindErr æFc Errors.h æT #define æD #define dsHMenuFindErr 86 /*Menu Manager Errors*/ æC æKY MacOSErr æFc Errors.h æT typedef æD extern short MacOSErr; æC æKY SysError æFc Errors.h æT Function æD pascal void SysError(short errorCode) = {0x301F,0xA9C9}; æDT SysError((short) errorCode); æMM æRI II-362, V-572 æC _____________________________________________________________________________________ Trap macro _SysError On entry D0: errorCode (word) On exit All registers changed _____________________________________________________________________________________ SysError generates a system error with the ID specified by the errorCode parameter. It takes the following precise steps: 1. It saves all registers and the stack pointer. 2. It stores the system error ID in a global variable (named DSErrCode). 3. It checks to see whether there's a system error alert table in memory (by testing whether the global variable DSAlertTab is 0); if there isn't, it draws the "sad Macintosh" icon. 4. It allocates memory for QuickDraw globals on the stack, initializes QuickDraw, and initializes a grafPort in which the alert box will be drawn. 5. It checks the system error ID. If the system error ID is negative, the alert box isn't redrawn (this is used for system startup alerts, which can display a sequence of consecutive messages in the same box). If the system error ID doesn't correspond to an entry in the system error alert table, the default alert definition at the start of the table will be used, displaying the message "Sorry, a system error occurred". 6. It draws an alert box (in the rectangle specified by the global variable DSAlertRect). 7. If the text definition IDs in the alert definition for this alert aren't 0, it draws both strings. 8. If the icon definition ID in the alert definition isn't 0, it draws the icon. 9. If the procedure definition ID in the alert definition isn't 0, it invokes the procedure with the specified ID. 10. If the button definition ID in the alert definition is 0, it returns control to the procedure that called it (this is used during the disk-switch alert to return control to the File Manager after the "Please insert the disk:" message has been displayed). 11. If there's a resume procedure, it increments the button definition ID by 1. 12. It draws the buttons. 13. It hit-tests the buttons and calls the corresponding procedure code when a button is pressed. If there's no procedure code, it returns to the procedure that called it. User Alerts _____________ ID Explanation 1 Bus error: Invalid memory reference; happens only on a Macintosh XL 2 Address error: Word or long-word reference made to an odd address 3 Illegal instruction: The MC68000 received an instruction it didn't recognize. 4 Zero divide: Signed Divide (DIVS) or Unsigned Divide (DIVU) instruction with a divisor of 0 was executed. 5 Check exception: Check Register Against Bounds (CHK) instruction was executed and failed. Pascal "value out of range" errors are usually reported in this way. 6 TrapV exception: Trap On Overflow (TRAPV) instruction was executed and failed. 7 Privilege violation: Macintosh always runs in supervisor mode; perhaps an erroneous Return From Execution (RTE) instruction was executed. 8 Trace exception: The trace bit in the status register is set. 9 Line 1010 exception: The 1010 trap dispatcher has failed. 10 Line 1111 exception: Unimplemented instruction 11 Miscellaneous exception: All other MC68000 exceptions 12 Unimplemented core routine: An unimplemented trap number was encountered. 13 Spurious interrupt: The interrupt vector table entry for a particular level of interrupt is NIL; usually occurs with level 4, 5, 6, or 7 interrupts. 14 I/O system error: The File Manager is attempting to dequeue an entry from an I/O request queue that has a bad queue type field; perhaps the queue entry is unlocked. Or, the dCtlQHead field was NIL during a Fetch or Stash call. Or, a needed device control entry has been purged. 15 Segment Loader error: A GetResource call to read a segment into memory failed. 16 Floating point error: The halt bit in the floating-point environment word was set. 17-24 Can't load package: A GetResource call to read a package into memory failed. 25 Can't allocate requested memory block in the heap 26 Segment Loader error: A GetResource call to read 'CODE' resource 0 into memory failed; usually indicates a nonexecutable file. 27 File map destroyed: A logical block number was found that's greater than the number of the last logical block on the volume or less than the logical block number of the first allocation block on the volume. 28 Stack overflow error: The stack has expanded into the heap. 30 "Please insert the disk:" File Manager alert 41 The file named "Finder" can't be found on the disk. 100 Can't mount system startup volume. The system couldn't read the system resource file into memory. 32767 "Sorry, a system error occurred": Default alert message æKY Events.h æKL Button EventAvail GetCaretTime GetDblTime GetKeys GetMouse GetNextEvent StillDown TickCount WaitMouseUp WaitNextEvent activateEvt activeFlag activMask adbAddrMask alphaLock app1Evt app1Mask app2Evt app2Mask app3Evt app3Mask app4Evt app4Mask autoKey autoKeyMask btnState charCodeMask childDiedMessage cmdKey controlKey diskEvt diskMask driverEvt driverMask EventRecord everyEvent keyCodeMask keyDown keyDownMask KeyMap keyUp keyUpMask mDownMask mouseDown mouseMovedMessage mouseUp mUpMask networkEvt networkMask nullEvent optionKey osEvt osEvtMessageMask shiftKey suspendResumeMessage updateEvt updateMask æKY nullEvent æFc Events.h æT #define æD #define nullEvent 0 æC »Event Code The what field of an event record contains an event code identifying the type of the event. The event codes are available as predefined constants: #define nullEvent 0 /*null*/ #define mouseDown 1 /*mouse-down*/ #define mouseUp 2 /*mouse-up*/ #define keyDown 4 /*key-down*/ #define keyUp 3 /*key-up*/ #define autoKey 5 /*auto-key*/ #define updateEvt 6 /*update*/ #define diskEvt 7 /*disk-inserted*/ #define activateEvt 8 /*activate*/ #define networkEvt 10 /*network*/ #define driverEvt 11 /*device driver*/ #define app1Evt 12 /*application-defined*/ #define app2Evt 13 /*application-defined*/ #define app3Evt 14 /*application-defined*/ #define app4Evt 15 /*application-defined*/ æKY mouseDown æFc Events.h æT #define æD #define mouseDown 1 æC æKY mouseUp æFc Events.h æT #define æD #define mouseUp 2 æC æKY keyDown æFc Events.h æT #define æD #define keyDown 3 æC æKY keyUp æFc Events.h æT #define æD #define keyUp 4 æC æKY autoKey æFc Events.h æT #define æD #define autoKey 5 æC æKY updateEvt æFc Events.h æT #define æD #define updateEvt 6 æC æKY diskEvt æFc Events.h æT #define æD #define diskEvt 7 æC æKY activateEvt æFc Events.h æT #define æD #define activateEvt 8 æC æKY networkEvt æFc Events.h æT #define æD #define networkEvt 10 æC æKY driverEvt æFc Events.h æT #define æD #define driverEvt 11 æC æKY app1Evt æFc Events.h æT #define æD #define app1Evt 12 æC æKY app2Evt æFc Events.h æT #define æD #define app2Evt 13 æC æKY app3Evt æFc Events.h æT #define æD #define app3Evt 14 æC æKY app4Evt æFc Events.h æT #define æD #define app4Evt 15 æC æKY osEvt æFc Events.h æT #define æD #define osEvt app4Evt æC æKY charCodeMask æFc Events.h æT #define æD #define charCodeMask 0x000000FF æC æKY keyCodeMask æFc Events.h æT #define æD #define keyCodeMask 0x0000FF00 æC æKY adbAddrMask æFc Events.h æT #define æD #define adbAddrMask 0x00FF0000 æC æKY osEvtMessageMask æFc Events.h æT #define æD #define osEvtMessageMask 0xFF000000 æC æKY mouseMovedMessage æFc Events.h æT #define æD /* OSEvent Messages */ #define mouseMovedMessage 0xFA æC æKY childDiedMessage æFc Events.h æT #define æD #define childDiedMessage 0xFD æC æKY suspendResumeMessage æFc Events.h æT #define æD #define suspendResumeMessage 0x01 æC æKY mDownMask æFc Events.h æT #define æD /* event mask equates */ #define mDownMask 2 æC _______________________________________________________________________________ »EVENT MASKS _______________________________________________________________________________ Some of the Event Manager routines can be restricted to operate on a specific event type or group of types; in other words, the specified event types are enabled while all others are disabled. For instance, instead of just requesting the next available event, you can specifically ask for the next keyboard event. You specify which event types a particular Event Manager call applies to by supplying an event mask as a parameter. This is an integer in which there’s one bit position for each event type, as shown in Figure 8. The bit position representing a given type corresponds to the event code for that type—for example, update events (event code 6) are specified by bit 6 of the mask. A 1 in bit 6 means that this Event Manager call applies to update events; a 0 means that it doesn’t. •••Refer to Figure 8.••• Figure 8–Event Mask Masks for each individual event type are available as predefined constants: #define mDownMask 2 /*mouse-down*/ #define mUpMask 4 /*mouse-up*/ #define keyDownMask 8 /*key-down*/ #define keyUpMask 16 /*key-up*/ #define autoKeyMask 32 /*auto-key*/ #define updateMask 64 /*update*/ #define diskMask 128 /*disk-inserted*/ #define activMask 256 /*activate*/ #define networkMask 1024 /*network*/ #define driverMask 2048 /*device driver*/ #define app1Mask 4096 /*application-defined*/ #define app2Mask 8192 /*application-defined*/ #define app3Mask 16384 /*application-defined*/ #define app4Mask -32768 /*application-defined*/ Note: Null events can’t be disabled; a null event will always be reported when none of the enabled types of events are available. The following predefined mask designates all event types: CONST everyEvent = -1; {all event types} You can form any mask you need by adding or subtracting these mask constants. For example, to specify every keyboard event, use keyDownMask + keyUpMask + autoKeyMask For every event except an update, use everyEvent - updateMask Note: It’s recommended that you always use the event mask everyEvent unless there’s a specific reason not to. There’s also a global system event mask that controls which event types get posted into the event queue. Only event types corresponding to bits set in the system event mask are posted; all others are ignored. When the system starts up, the system event mask is set to post all except key-up event—that is, it’s initialized to everyEvent - keyUpMask Note: Key-up events are meaningless for most applications. Your application will usually want to ignore them; if not, it can set the system event mask with the Operating System Event Manager procedure SetEventMask. æKY mUpMask æFc Events.h æT #define æD #define mUpMask 4 æC æKY keyDownMask æFc Events.h æT #define æD #define keyDownMask 8 æC æKY keyUpMask æFc Events.h æT #define æD #define keyUpMask 16 æC æKY autoKeyMask æFc Events.h æT #define æD #define autoKeyMask 32 æC æKY updateMask æFc Events.h æT #define æD #define updateMask 64 æC æKY diskMask æFc Events.h æT #define æD #define diskMask 128 æC æKY activMask æFc Events.h æT #define æD #define activMask 256 æC æKY networkMask æFc Events.h æT #define æD #define networkMask 1024 æC æKY driverMask æFc Events.h æT #define æD #define driverMask 2048 æC æKY app1Mask æFc Events.h æT #define æD #define app1Mask 4096 æC æKY app2Mask æFc Events.h æT #define æD #define app2Mask 8192 æC æKY app3Mask æFc Events.h æT #define æD #define app3Mask 16384 æC æKY app4Mask æFc Events.h æT #define æD #define app4Mask -32768 æC æKY everyEvent æFc Events.h æT #define æD #define everyEvent -1 æC æKY activeFlag æFc Events.h æT #define æD /* modifiers */ #define activeFlag 1 /*bit 0 of modifiers for activate event*/ æC »Modifier Flags As mentioned above, the modifiers field of an event record contains further information about activate events and the state of the modifier keys and mouse button at the time the event was posted (see Figure 7). You might look at this field to find out, for instance, whether the Command key was down when a mouse-down event was posted (which in many applications affects the way objects are selected) or when a key-down event was posted (which could mean the user is choosing a menu item by typing its keyboard equivalent). •••Refer to Figure 7.••• Figure 7–Modifier Flags The following predefined constants are useful as masks for reading the flags in the modifiers field: #define activeFlag 1 /*set if window being activated*/ #define btnState 128 /*set if mouse button up*/ #define cmdKey 256 /*set if Command key down*/ #define shiftKey 512 /*set if Shift key down*/ #define alphaLock 1024 /*set if Caps Lock key down*/ #define optionKey 2048 /*set if Option key down*/ #define controlKey 4096 /*set if Control key down*/ The activeFlag bit gives further information about activate events; it’s set if the window pointed to by the event message is being activated, or 0 if the window is being deactivated. The remaining bits indicate the state of the mouse button and modifier keys. Notice that the btnState bit is set if the mouse button is up, whereas the bits for the four modifier keys are set if their corresponding keys are down. æKY btnState æFc Events.h æT #define æD #define btnState 128 /*Bit 7 of low byte is mouse button state*/ æC æKY cmdKey æFc Events.h æT #define æD #define cmdKey 256 /*Bit 0*/ æC æKY shiftKey æFc Events.h æT #define æD #define shiftKey 512 /*Bit 1*/ æC æKY alphaLock æFc Events.h æT #define æD #define alphaLock 1024 /*Bit 2 */ æC æKY optionKey æFc Events.h æT #define æD #define optionKey 2048 /*Bit 3 of high byte*/ æC æKY controlKey æFc Events.h æT #define æD #define controlKey 4096 æC æKY KeyMap æFc Events.h æT typedef æD typedef long KeyMap[4]; æC æKY EventRecord æFc Events.h æT struct æD struct EventRecord { short what; long message; long when; Point where; short modifiers; }; typedef struct EventRecord EventRecord; æC _______________________________________________________________________________ »EVENT RECORDS _______________________________________________________________________________ Every event is represented internally by an event record containing all pertinent information about that event. The event record includes the following information: • the type of event • the time the event was posted (in ticks since system startup) • the location of the mouse at the time the event was posted (in global coordinates) • the state of the mouse button and modifier keys at the time the event was posted • any additional information required for a particular type of event, such as which key the user pressed or which window is being activated Every event has an event record containing this information—even null events. Event records are defined as follows: TYPE EventRecord = RECORD what: INTEGER; {event code} message: LONGINT; {event message} when: LONGINT; {ticks since startup} where: Point; {mouse location} modifiers: INTEGER {modifier flags} END; The when field contains the number of ticks since the system last started up, and the where field gives the location of the mouse, in global coordinates, at the time the event was posted. The other three fields are described below. _______________________________________________________________________________ »Event Code The what field of an event record contains an event code identifying the type of the event. The event codes are available as predefined constants: CONST nullEvent = 0; {null} mouseDown = 1; {mouse-down} mouseUp = 2; {mouse-up} keyDown = 3; {key-down} keyUp = 4; {key-up} autoKey = 5; {auto-key} updateEvt = 6; {update} diskEvt = 7; {disk-inserted} activateEvt = 8; {activate} networkEvt = 10; {network} driverEvt = 11; {device driver} app1Evt = 12; {application-defined} app2Evt = 13; {application-defined} app3Evt = 14; {application-defined} app4Evt = 15; {application-defined} _______________________________________________________________________________ »Event Message The message field of an event record contains the event message, which conveys additional important information about the event. The nature of this information depends on the event type, as summarized in the following table and described below. Event type Event message Keyboard Character code, key code, and ADB address field Activate, update Pointer to window Disk-inserted Drive number in low-order word, File Manager result code in high-order word Mouse-down, Undefined mouse-up, null Network Handle to parameter block Device driver See chapter describing driver Application-defined Whatever you wish For keyboard events, the low-order byte of the low-order word of the event message contains the ASCII character code generated by the key or combination of keys that was pressed or released; usually this is all you’ll need. However, as described in the Apple Desktop Bus chapter, the Macintosh II and SE can be connected to multiple keyboards. To identify the origin of keyboard events, the keyboard event message contains a new ADB address field. It now has the structure shown in Figure 2. Warning: The high byte of the event message for keyboard events is reserved for future use, and is not presently guaranteed to be zero. The event message for non-keyboard events remains the same as described above. •••Refer to Figure 2.••• Figure 2–Event Message for Keyboard Events The key code in the event message for a keyboard event represents the character key that was pressed or released; this value is always the same for any given character key, regardless of the modifier keys pressed along with it. Key codes are useful in special cases—in a music generator, for example—where you want to treat the keyboard as a set of keys unrelated to characters. Figure 3 gives the key codes for all the keys on the keyboard and keypad. (Key codes are shown for modifier keys here because they’re meaningful in other contexts, as explained later.) Both the U.S. and international keyboards are shown; in some cases the codes are quite different (for example, space and Enter are reversed). Three keyboards are now available as standard equipment with Macintosh computers sold in the U.S. They are • The Macintosh Plus Keyboard, which includes cursor control keys and an integral keypad. Its layout and key coding is shown in Figure 4. • The Macintosh II Keyboard, also shipped with the Macintosh SE, which adds Esc (Escape) and Control keys and is connected to the Apple Desktop Bus. Its layout and key coding is shown in Figure 5. • The Apple Extended Keyboard, which the user may connect to the Apple Desktop Bus of any Macintosh II or Macintosh SE computer. Its layout and key coding is shown in Figure 6. These figures show the virtual key codes for each key; they are the key codes that actually appear in keyboard events. In the case of the Macintosh II and Apple Extended Keyboards, however, the hardware produces raw key codes, which may be different. Raw key codes are translated to virtual key codes by the 'KMAP' resource in the System Folder. By modifying the 'KMAP' resource you can change the key codes for any keys. Similarly, you can change the ASCII codes corresponding to specific key codes by modifying the 'KCHR' resource in the System Folder. The 'KMAP' and 'KCHR' resources are described in the Resource Manager chapter. With both the Macintosh II and the Apple Extended keyboards, the standard 'KMAP' resource supplied in the system folder reassigns the following raw key codes to different virtual key codes: Key Raw key code Virtual key code Control 36 3B Left cursor 3B 7B Right cursor 3C 7C Down cursor 3D 7D Up cursor 3E 7E The standard 'KMAP' resource leaves all other raw key codes and virtual key codes the same. With the Apple Extended Keyboard, the virtual key codes for three more keys may be easily reassigned, as described above under “Reassigning Right Key Codes”. The following predefined constants are available to help you access the character code and key code: CONST charCodeMask = $000000FF; {character code} keyCodeMask = $0000FF00; {key code} •••Refer to Figure 3.••• Figure 3–Key Codes •••Refer to Figure 4.••• Figure 4–Macintosh Plus Keyboard •••Refer to Figure 5.••• Figure 5–Macintosh II Keyboard •••Refer to Figure 6.••• Figure 6–Apple Extended Keyboard Note: You can use the Toolbox Utility function BitAnd with these constants; for instance, to access the character code, use charCode := BitAnd(my Event.message,charCodeMask) _______________________________________________________________________________ THE TOOLBOX EVENT MANAGER _______________________________________________________________________________ For activate and update events, the event message is a pointer to the window affected. (If the event is an activate event, additional important information about the event can be found in the modifiers field of the event record, as described below.) For disk-inserted events, the low-order word of the event message contains the drive number of the disk drive into which the disk was inserted: 1 for the Macintosh’s built-in drive, and 2 for the external drive, if any. Numbers greater than 2 denote additional disk drives connected to the Macintosh. By the time your application receives a disk-inserted event, the system will already have attempted to mount the volume on the disk by calling the File Manager function MountVol; the high-order word of the event message will contain the result code returned by MountVol. For mouse-down, mouse-up, and null events, the event message is undefined and should be ignored. The event message for a network event contains a handle to a parameter block, as described in the AppleTalk Manager chapter. For device driver events, the contents of the event message depend on the situation under which the event was generated; the chapters describing those situations will give the details. Finally, you can use the event message however you wish for application-defined event types. _______________________________________________________________________________ »Modifier Flags As mentioned above, the modifiers field of an event record contains further information about activate events and the state of the modifier keys and mouse button at the time the event was posted (see Figure 7). You might look at this field to find out, for instance, whether the Command key was down when a mouse-down event was posted (which in many applications affects the way objects are selected) or when a key-down event was posted (which could mean the user is choosing a menu item by typing its keyboard equivalent). •••Refer to Figure 7.••• Figure 7–Modifier Flags The following predefined constants are useful as masks for reading the flags in the modifiers field: CONST activeFlag = 1; {set if window being activated} btnState = 128; {set if mouse button up} cmdKey = 256; {set if Command key down} shiftKey = 512; {set if Shift key down} alphaLock = 1024; {set if Caps Lock key down} optionKey = 2048; {set if Option key down} ControlKey = 4096; {set if Control key down} The activeFlag bit gives further information about activate events; it’s set if the window pointed to by the event message is being activated, or 0 if the window is being deactivated. The remaining bits indicate the state of the mouse button and modifier keys. Notice that the btnState bit is set if the mouse button is up, whereas the bits for the four modifier keys are set if their corresponding keys are down. æKY GetNextEvent æFc Events.h æT Function æTN A970 æD pascal Boolean GetNextEvent(short eventMask,EventRecord *theEvent) = 0xA970; æDT Boolean myVariable = GetNextEvent((short) eventMask,(EventRecord *) theEvent); æMM æRT 3, 5, 85, 194, 205 æRI I-257, N3-1, N5-1, N85, P-30, 32, 34, 39, 40, 97, 108, 173 æC GetNextEvent returns the next available event of a specified type or types and, if the event is in the event queue, removes it from the queue. The event is returned in the parameter theEvent. The eventMask parameter specifies which event types are of interest. GetNextEvent returns the next available event of any type designated by the mask, subject to the priority rules discussed above under “Priority of Events”. If no event of any of the designated types is available, GetNextEvent returns a null event. Note: Events in the queue that aren’t designated in the mask are kept in the queue; if you want to remove them, you can do so by calling the Operating System Event Manager procedure FlushEvents. Before reporting an event to your application, GetNextEvent first calls the Desk Manager function SystemEvent to see whether the system wants to intercept and respond to the event. If so, or if the event being reported is a null event, GetNextEvent returns a function result of FALSE; a function result of TRUE means that your application should handle the event itself. The Desk Manager intercepts the following events: • activate and update events directed to a desk accessory • mouse-up and keyboard events, if the currently active window belongs to a desk accessory Note: In each case, the event is intercepted by the Desk Manager only if the desk accessory can handle that type of event; however, as a rule all desk accessories should be set up to handle activate, update, and keyboard events and should not handle mouse-up events. The Desk Manager also intercepts disk-inserted events: It attempts to mount the volume on the disk by calling the File Manager function MountVol. GetNextEvent will always return TRUE in this case, though, so that your application can take any further appropriate action after examining the result code returned by MountVol in the event message. (See the Desk Manager and File Manager chapters.) GetNextEvent returns TRUE for all other non-null events (including all mouse-down events, regardless of which window is active), leaving them for your application to handle. GetNextEvent also makes the following processing happen, invisible to your program: • If the “alarm” is set and the current time is the alarm time, the alarm goes off (a beep followed by blinking the apple symbol in the menu bar). The user can set the alarm with the Alarm Clock desk accessory. • If the user holds down the Command and Shift keys while pressing a numeric key that has a special effect, that effect occurs. The standard such keys are 1 and 2 for ejecting the disk in the internal or external drive, and 3 and 4 for writing a snapshot of the screen to a MacPaint document or to the printer. Note: Advanced programmers can implement their own code to be executed in response to Command-Shift-number combinations (except for Command- Shift-1 and 2, which can’t be changed). The code corresponding to a particular number must be a routine having no parameters, stored in a resource whose type is 'FKEY' and whose ID is the number. The system resource file contains code for the numbers 3 and 4. Assembly-language note: You can disable GetNextEvent’s processing of Command- Shift-number combinations by setting the global variable ScrDmpEnb (a byte) to 0. æKY WaitNextEvent æFc Events.h æT Function æTN A860 æD pascal Boolean WaitNextEvent(short mask,EventRecord *event,unsigned long sleep, RgnHandle mouseRgn) = 0xA860; æDT Boolean myVariable = WaitNextEvent((short) mask,(EventRecord *) event,(unsigned long) sleep,() RgnHandle mouseRgn); æRT 158, 177, 180, 194, 205 æRI N158-1 æC æKY EventAvail æFc Events.h æT Function æTN A971 æD pascal Boolean EventAvail(short eventMask,EventRecord *theEvent) = 0xA971; æDT Boolean myVariable = EventAvail((short) eventMask,(EventRecord *) theEvent); æMM æRT 194 æRI I-259 æC EventAvail works exactly the same as GetNextEvent except that if the event is in the event queue, it’s left there. Note: An event returned by EventAvail will not be accessible later if in the meantime the queue becomes full and the event is discarded from it; since the events discarded are always the oldest ones in the queue, however, this will happen only in an unusually busy environment. æKY GetMouse æFc Events.h æT Function æTN A972 æD pascal void GetMouse(Point *mouseLoc) = 0xA972; æDT GetMouse((Point *) mouseLoc); æMM æRI I-259 æC GetMouse returns the current mouse location in the mouseLoc parameter. The location is given in the local coordinate system of the current grafPort (which might be, for example, the currently active window). Notice that this differs from the mouse location stored in the where field of an event record; that location is always in global coordinates. æKY Button æFc Events.h æT Function æTN A974 æD pascal Boolean Button(void) = 0xA974; æDT Boolean myVariable = Button()(void); æMM æRI I-259 æC The Button function returns TRUE if the mouse button is currently down, and FALSE if it isn’t. æKY StillDown æFc Events.h æT Function æTN A973 æD pascal Boolean StillDown(void) = 0xA973; æDT Boolean myVariable = StillDown()(void); æMM æRT 194 æRI I-259 æC Usually called after a mouse-down event, StillDown tests whether the mouse button is still down. It returns TRUE if the button is currently down and there are no more mouse events pending in the event queue. This is a true test of whether the button is still down from the original press—unlike Button (above), which returns TRUE whenever the button is currently down, even if it has been released and pressed again since the original mouse-down event. æKY WaitMouseUp æFc Events.h æT Function æTN A977 æD pascal Boolean WaitMouseUp(void) = 0xA977; æDT Boolean myVariable = WaitMouseUp()(void); æMM æRT 194 æRI I-259 æC WaitMouseUp works exactly the same as StillDown (above), except that if the button is not still down from the original press, WaitMouseUp removes the preceding mouse-up event before returning FALSE. If, for instance, your application attaches some special significance both to mouse double-clicks and to mouse-up events, this function would allow your application to recognize a double-click without being confused by the intervening mouse-up. æKY GetKeys æFc Events.h æT Function æTN A976 æD pascal void GetKeys(KeyMap theKeys) = 0xA976; æDT GetKeys((KeyMap) theKeys); æMM æRI I-259 æC GetKeys reads the current state of the keyboard (and keypad, if any) and returns it in the form of a keyMap: TYPE KeyMap = PACKED ARRAY[0..127] OF BOOLEAN; Each key on the keyboard or keypad corresponds to an element in the keyMap. The index into the keyMap for a particular key is the same as the key code for that key. (The key codes are shown in Figure 3 above.) The keyMap element is TRUE if the corresponding key is down and FALSE if it isn’t. The maximum number of keys that can be down simultaneously is two character keys plus any combination of the four modifier keys. æKY TickCount æFc Events.h æT Function æTN A975 æD pascal unsigned long TickCount(void) = 0xA975; æDT unsigned long myVariable = TickCount()(void); æMM æRI I-260 æC TickCount returns the current number of ticks (sixtieths of a second) since the system last started up. Warning: Don’t rely on the tick count being exact; it will usually be accurate to within one tick, but may be off by more than that. The tick count is incremented during the vertical retrace interrupt, but it’s possible for this interrupt to be disabled. Furthermore, don’t rely on the tick count being incremented to a certain value, such as testing whether it has become equal to its old value plus 1; check instead for “greater than or equal to” (since an interrupt task may keep control for more than one tick). Assembly-language note: The value returned by this function is also contained in the global variable Ticks. æKY GetDblTime æFc Events.h æT Function æD pascal unsigned long GetDblTime(void) = {0x2EB8,0x02F0}; æDT unsigned long myVariable = GetDblTime()(void); æRI I-260 æC [Not in ROM] GetDblTime returns the suggested maximum difference (in ticks) that should exist between the times of a mouse-up event and a mouse-down event for those two mouse clicks to be considered a double-click. The user can adjust this value by means of the Control Panel desk accessory. Assembly-language note: This value is available to assembly-language programmers in the global variable DoubleTime. æKY GetCaretTime æFc Events.h æT Function æD pascal unsigned long GetCaretTime(void) = {0x2EB8,0x02F4}; æDT unsigned long myVariable = GetCaretTime()(void); æRI I-260 æC [Not in ROM] GetCaretTime returns the time (in ticks) between blinks of the “caret” (usually a vertical bar) marking the insertion point in editable text. If you aren’t using TextEdit, you’ll need to cause the caret to blink yourself; on every pass through your program’s main event loop, you should check this value against the elapsed time since the last blink of the caret. The user can adjust this value by means of the Control Panel desk accessory. Assembly-language note: This value is available to assembly-language programmers in the global variable CaretTime. æKY FCntl.h æC close faccess open unlink creat fcntl read write dup lseek F_DELETE F_OPEN O_APPEND O_RDWR F_DUPFD F_RENAME O_CREAT O_RSRC F_GFONTINFO F_SFONTINFO O_EXCL O_TRUNC F_GPRINTREC F_SPRINTREC O_RDONLY O_WRONLY F_GTABINFO F_STABINFO Low-level file I/O (non-ANSI extensions)—FCntl.h non-ANSI extensions:low-level file I/O MPW 3.0 C contains several file-control functions in addition to those required by the ANSI draft C standard. These functions, declared in the header file FCntl.h, preserve compatibility with MPW 2.0 C. Some of these functions duplicate, at a lower level, functions in the header file StdIO.h. (For example, open is a low-level equivalent of fopen.) Using the StdIO.h functions whenever possible will improve portability and robustness. æKY close æFc FCntl.h æC Synopsis #include <FCntl.h> int close(int fildes); Description The close; function closes the file descriptor indicated by fildes. Parameter fildes is a file descriptor obtained from an open, creat, dup, or fcntl call. The function close fails if fildes is not a valid open file descriptor [EBADF]. Diagnostics Upon successful completion, a value of 0 is returned. Otherwise, a value of –1 is returned and errno is set to indicate the error. See also creat, dup, fclose, fcntl, ferror, open, stdio æKY creat æFc FCntl.h æC Synopsis #include <FCntl.h> int creat(const char *filename); Description The creat; function creates a new file or prepares to rewrite an existing file, filename. If the file exists, the length of its data fork is set to 0. The function creat(filename) is equivalent to open(filename, O_WRONLY|O_TRUNC|O_CREAT) Upon successful completion, a nonnegative integer (the file descriptor) is returned and the file is open for writing. The file pointer is set to the beginning of the file. A maximum of about 30 files may be open at a given time: the actual maximum depends upon the current system environment. Return value Upon successful completion, a nonnegative integer (the file descriptor) is returned. Otherwise, a value of –1 is returned and errno is set to indicate the error. Note Other implementations of creat specify a second parameter, mode. This version ignores any second parameter. See also close, open, read, write æKY dup æFc FCntl.h æC Synopsis #include <Fcntl.h> int dup(int fildes); Description The dup; function returns a new file descriptor with these features: It refers to the same open file as the original. It uses the same file pointer as the original. It has the same access mode (that is, read, write, or read/write) as the original. The fildes parameter is a file descriptor obtained from an open, creat, dup, or fcntl call. The new file descriptor returned by dup is the lowest one available. The function call dup(fildes) is equivalent to fcntl(fildes, F_DUPFD, 0). The dup function fails if parameter fildes is not a valid open file descriptor [EBADF]. Return value Upon successful completion, a nonnegative integer (the file descriptor) is returned. Otherwise, a value of –1 is returned and errno is set to indicate the error. See also close, fcntl, ferror, open æKY F_DELETE æFc FCntl.h æD #define F_DELETE (('d'<<8)|01) æKY F_DUPFD æFc FCntl.h æD #define F_DUPFD 0 /*Duplicate fildes*/ æKY F_GFONTINFO æFc FCntl.h æD #define F_GFONTINFO (('e'<<8)|02) æKY F_GPRINTREC æFc FCntl.h æD #define F_GPRINTREC (('e'<<8)|04) æKY F_GTABINFO æFc FCntl.h æD #define F_GTABINFO (('e'<<8)|00) /*'e' => "editor" ops*/ æKY F_OPEN æFc FCntl.h æD #define F_OPEN (('d'<<8)|00) /*d' => "directory" ops*/ æKY F_RENAME æFc FCntl.h æD #define F_RENAME (('d'<<8)|02) æKY F_SFONTINFO æFc FCntl.h æD #define F_SFONTINFO (('e'<<8)|03) æKY F_SPRINTREC æFc FCntl.h æD #define F_SPRINTREC (('e'<<8)|05) æKY F_STABINFO æFc FCntl.h æD #define F_STABINFO (('e'<<8)|01) æKY faccess æFc FCntl.h æC Synopsis #include <FCntl.h> int faccess(const char *filename, unsigned int cmd, long *arg); Description The faccess; function provides access to control and status information for named files. (Compare function ioctl, which provides different control and status information for open files.) The cmd parameter must be set to one of the constants in the following list to indicate what operation is to be performed on the file. As Noted in the list, some calls to faccess also require the arg parameter, usually as a long or as a pointer to a long. The following commands are available to all programs: Value of cmd Description F_DELETE Deletes the named file, or returns an error if the file is open. Parameter arg is ignored. F_RENAME Renames the named file. Parameter arg is a pointer to a string containing the new name. The following commands can be used only by MPW tools: Value of cmd Description F_GTABINFO Gets the tab offset for the MPW text file filename. The tab offset is stored in the long integer pointed to by arg. The tab offset is expressed as an integer number of spaces. The width of the space character in the current font determines the actual distance of the tab offset. F_STABINFO Sets the tab offset for the MPW text file filename. The tab offset is specified as a long value in arg. F_GFONTINFO Gets the font number and font size for an MPW text file filename. The font number is stored in the high-order half of the long pointed to by arg; the font size is stored in the low order half of the same long. F_SFONTINFO Sets the font number and font size for the MPW text file, filename. The font number is specified in the high-order half of arg; the font size is specified in the low-order half of arg. F_GPRINTREC Gets a print record TPrint for an MPW text file, filename; arg is a handle to the print record. F_SPRINTREC Sets a print record for the MPW text file filename; arg is a handle to the print record. F_OPE Reserved for operating system use. F_GSELINFO Gets the selection information for the MPW text file filename. F_SSELINFO Sets the selection information for the MPW text file filename. F_GWININFO Gets the current window position. F_SWININFO Sets the current window position. The commands F_GTABINFO and F_GFONTINFO pass arg as a pointer to a long; F_STABINFO and F_SFONTINFO pass arg as a long value; and F_GPRINTREC and F_SPRINTREC pass arg as a handle to a print record. Return values Upon successful completion, faccess returns a nonnegative value, usually 0. If the device for the named file cannot perform the requested command, faccess returns –1 and errno is set to indicate the error. If the requested resource for F_GTABINFO, F_GFONTINFO, or F_GPRINTREC does not exist for the named file, default values are stored and the function returns a value greater than 0. Note Before faccess is called with F_GPRINTREC or F_SPRINTREC, the Printing Manager must be initialized and the print record handle THPrint must be allocated. The font size must be 9, 10, 12, 14, 18, or 24; the font number must be 0 or a positive integer. The following sequence must be used with these print command values: res = CurResFile(); PRClose(); UseResFile(res); PROpen(); /* do whatever, including call faccess print commands */ PRClose(); UseResFile(res); See also ioctl, unlink æKY fcntl æFc FCntl.h æC Synopsis #include <FCntl.h> int fcntl(int fildes, unsigned int cmd, int arg); Description The fcntl; function duplicates a file descriptor. A file remains open until all of its file descriptors are closed. The fildes parameter is an open file descriptor obtained from an open, creat, dup, or fcntl call. The cmd parameter takes the value F_DUPFD, which tells fcntl to return the lowest-numbered available file descriptor greater than or equal to arg. Normally arg is greater than or equal to 3, to avoid obtaining the standard file descriptors 0, 1, and 2. The function fcntl returns a new file descriptor that points to the same open file as fildes. The new file descriptor has the same access mode (read, write, or read/write) and file pointer as fildes. Any I/O operation changes the file pointer for all file descriptors that share it. The fcntl function fails if one or more of the following error conditions are true: Parameter fildes is not a valid open file descriptor [EBADF]. Parameter arg is negative or greater than the highest allowable file descriptor [EINVAL]. Return values Upon successful completion, the value returned is a new file descriptor. Otherwise, a value of –1 is returned and errno is set to indicate the error. Note MPW 3.0 C does not support the F_GETFD, F_SETFD, F_GETFL, and F_SETFL commands of fcntl. See also close, dup, ferror, ioctl, open æKY lseek æFc FCntl.h æC Synopsis #include <FCntl.h> #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 long lseek(int fildes, long int offset, int whence); Description A file descriptor, fildes, is returned from a call to creat, dup, fcntl, or open. The lseek; function sets the file pointer associated with fildes, thus determining the position of the next read or write operation. The value of whence determines how the offset parameter is used, according to these rules: If whence is SEEK_SET, the new position is offset bytes from the beginning of the file. If whence is SEEK_CUR, the new position is the current location plus offset. If whence is SEEK_END, the new position is the size of the file plus offset. If whence is SEEK_SET or SEEK_CUR, the value of offset may be negative. Upon successful completion, the file-pointer value as measured in bytes from the beginning of the file is returned. The file pointer remains unchanged and lseek fails if one or more of the following error conditions are true: File descriptor fildes is not open [EBADF]. Parameter whence is not equal to SEEK_SET, SEEK_CUR, or SEEK_END [EINVAL]. The resulting file pointer would point past the end-of-file [ESPIPE]. The resulting file pointer would point before the beginning of the file [EINVAL]. Some devices are incapable of seeking. The value of the file pointer associated with such a device is undefined. Return values Upon successful completion, a nonnegative long integer indicating the file-pointer value is returned. Otherwise, a value of –1 is returned and errno is set to indicate the error. Note In previous versions of the Standard C Library, tell;(fildes) was a function that returned the current file position. It is equivalent to the call lseek(fildes, 0L, 1). Warning The lseek function has no effect on a file opened with the O_APPEND flag because the next write to the file always repositions the file pointer to the end before writing. See also ferror, fseek, open, stdio, write æKY O_APPEND æFc FCntl.h æD #define O_APPEND (1<<3) /*append (writes guaranteed at the end)*/ æKY O_CREAT æFc FCntl.h æD #define O_CREAT (1<<8) /*Open with file create*/ æKY O_EXCL æFc FCntl.h æD #define O_EXCL (1<<10) /*Exclusive open*/ æKY O_RDONLY æFc FCntl.h æD #define O_RDONLY 0 /*Bits 0 and 1 are used internally*/ æKY O_RDWR æFc FCntl.h æD #define O_RDWR 2 æKY O_RSRC æFc FCntl.h æD #define O_RSRC (1<<4) /*Open the resource fork*/ æKY O_TRUNC æFc FCntl.h æD #define O_TRUNC (1<<9) /*Open with truncation*/ æKY O_WRONLY æFc FCntl.h æD #define O_WRONLY 1 /*Values 0..2 are historical*/ æKY open æFc FCntl.h æC Synopsis #include <FCntl.h> int open(const char *filename, int oflag); Description The open; function opens a file descriptor for the named file and sets the file-status flags according to the value of oflag. The parameter filename is a disk file, window, selection, or pseudofile. (See “Pseudo-Filenames” in Chapter 5 of the Macintosh Programmer’s Workshop 3.0 Reference for more information.) The value of oflag is constructed by performing an OR operation on the flag settings, for example: fildes = open("MyFile", O_WRONLY|O_CREAT|O_TRUNC); To construct oflag, first select one of the following access modes: O_RDONLY Open for reading only. WR_ONLY Open for writing only. O_RDWR Open for reading and writing. Then optionally add one or more of these modifiers: O_APPEND The file pointer is set to the end of the file before each write. O_CREAT If the file does not exist, it is created. O_TRUNC If the file exists, its length is truncated to 0; the mode is unchanged. O_RSRC The file’s resource fork is opened. (Normally, the data fork is opened.) O_BINARY Open as a binary stream (supported but not used by the system). The following setting is valid only if O_CREAT is also specified: O_EXCL The function open fails if the file exists. Upon successful completion, a nonnegative integer (the file descriptor) is returned. The file pointer used to mark the current position within the file is set to the beginning of the file. The named file is opened unless one or more of the following error conditions is true: O_CREAT is not set and the named file does not exist [ENOENT]. More than about 30 file descriptors are currently open. The actual limit varies according to run-time conditions [EMFILE]. O_CREAT and O_EXCL are set and the named file exists [EEXIST]. Return value Upon successful completion, a nonnegative integer (the file descriptor) is returned. Otherwise, a value of –1 is returned and errno is set to indicate the error. See also close, creat, dup, fcntl, ferror, fopen, lseek, read, stdio, write æKY read æFc FCntl.h æC Synopsis #include <Fcntl.h> int read(int fildes, char* buf, unsigned long nbyte); Description The read; function transfers up to nbyte bytes from the file associated with fildes into the buffer pointed to by buf. File descriptor fildes is obtained from a call to open, creat, a, or a. On devices capable of seeking, read starts reading at the current position of the file pointer associated with fildes. Upon return from read, the file pointer is incremented by the number of bytes actually read. Nonseeking devices always read from the current position. The value of a file pointer associated with such a file is undefined. Upon successful completion, read returns the number of bytes actually read and placed in the buffer. This number may be less than nbyte if the file is associated with a window or if the number of bytes left in the file is less than nbyte bytes. A value of 0 is returned when an end-of-file has been reached, and a value of –1 is returned if a read error occurred. The function read fails if fildes is not a valid file descriptor open for reading. [EBADF] File descriptor 0 is opened by the MPW Shell as standard input. Return values Upon successful completion, a nonnegative integer is returned, indicating the number of bytes actually read. Otherwise, –1 is returned and errno is set to indicate the error. See also creat, ferror, fread, open, stdio æKY unlink æFc FCntl.h æC Synopsis #include <FCntl.h> int unlink(const char *fileName); Description The unlink; function deletes the named file. The function fails if the named file is open. This function is the UNIX (and MPW 2.0 C) equivalent of the ANSI remove function, and is included for compatibility. A call to unlink is equivalent to faccess(fileName, F_DELETE, 0) Diagnostics Upon successful completion, a value of 0 is returned. Otherwise, a value of –1 is returned and errno is set to indicate the error. See also faccess æKY write æFc FCntl.h æC Synopsis #include <Fcntl.h> int write(int fildes, const char* buf, unsigned long nbyte); Description The write; function attempts to write nbyte bytes from the buffer pointed to by buf to the file associated with the fildes. File descriptor fildes is obtained from an open, creat, dup, or fcntl call. Internal limitations may cause write to write fewer bytes than requested; the number of bytes actually written is indicated by the return value. Several calls to write may therefore be necessary to write out the contents of buf. On devices capable of seeking, the actual writing of data proceeds from the position in the file indicated by the file pointer. Upon return from write, the file pointer is incremented by the number of bytes actually written. On nonseeking devices, writing starts at the current position. The value of a file pointer associated with such a device is undefined. If the O_APPEND file-status flag set in open is on, the file pointer is set to end-of-file before each write. The file pointer remains unchanged and write fails if fildes is not a valid file descriptor open for writing [EBADF]. If you try to write more bytes than there is room for on the device, write writes as many bytes as possible. For example, if nbyte is 512 and there is room for 20 bytes more on the device, write writes 20 bytes and returns a value of 20. The next attempt to write a nonzero number of bytes will return an error [ENOSPC]. File descriptor 1 is opened by the MPW Shell as standard output; file descriptor 2, as standard error. Return value Upon successful completion, the number of bytes actually written is returned. Otherwise, –1 is returned and errno is set to indicate the error. See also creat, ferror, fread, lseek, open, stdio æKY closeæ æDT int myVariabel = close((int) fildes); æKY creatæ æDT int myVariable = creat((const char *)filename); æKY dupæ æDT int myVariable = dup((int) fildes); æKY faccessæ æDT int myVariablle =faccess((const char *)filename, (unsigned int) cmd, (long *)arg); æKY fcntlæ æDT int myVaraible = fcntl((int) fildes, (unsigned int) cmd, (int) arg); æKY lseekæ æDT long myVariable = lseek((int) fildes, (long int) offset, (int) whence); æKY openæ æDT int myVariable = open((const char *)filename, (int) oflag); æKY readæ æDT int myVariable = read((int) fildes, (char*) buf, (unsigned long) nbyte); æKY unlinkæ æDT int myVariable = unlink((const char *)fileName); æKY writeæ æDT int myVariable = write((int) fildes, (const char*) buf, (unsigned long) nbyte); æKY Files.h æKL AddDrive Allocate AllocContig CatMove CloseWD Create create DirCreate Eject eject FInitQueue flushvol FlushVol FSClose FSDelete fsdelete fsopen FSOpen FSpCatMove FSpCreate FSpCreateResFile FSpDelete FSpDirCreate FSpGetFInfo FSpOpenDF FSpOpenResFile FSpOpenRF FSpRename FSpRstFLock FSpSetFInfo FSpSetFLock FSRead fsrename FSWrite GetDrvQHdr GetEOF GetFInfo getfinfo GetFPos GetFSQHdr GetVCBQHdr getvinfo GetVInfo GetVol getvol GetVRefNum GetWDInfo HCreate HDelete HGetFInfo HGetVol HOpen HOpenRF HRename HRstFLock HSetFInfo HSetFLock HSetVol MakeFSSpec OpenRF openrf OpenWD PBAllocate PBAllocContig PBCatMove PBCatSearch PBClose PBCloseWD PBCreate PBCreateFileID PBDelete PBDeleteFileID PBDirCreate PBDTAddAPPL PBDTAddIcon PBDTCloseDown PBDTDelete PBDTFlush PBDTGetAPPL PBDTGetComment PBDTGetIcon PBDTGetIconInfo PBDTGetInfo PBDTGetPath PBDTOpenInform PBDTRemoveAPPL PBDTRemoveComment PBDTReset PBDTSetComment PBEject PBExchangeFiles PBFlushFile PBFlushVol PBGetAltAccess PBGetCatInfo PBGetEOF PBGetFCBInfo PBGetFInfo PBGetFPos PBGetVInfo PBGetVol PBGetWDInfo PBHCopyFile PBHCreate PBHDelete PBHGetDirAccess PBHGetFInfo PBHGetLogInInfo PBHGetVInfo PBHGetVol PBHGetVolParms PBHMapID PBHMapName PBHMoveRename PBHOpen PBHOpenDeny PBHOpenDF PBHOpenRF PBHOpenRFDeny PBHRename PBHRstFLock PBHSetDirAccess PBHSetFInfo PBHSetFLock PBHSetVol PBLockRange PBMakeFSSpec PBMountVol PBOffLine PBOpen PBOpenDF PBOpenRF PBOpenWD PBRead PBRename PBResolveFileID PBRstFLock PBSetAltAccess PBSetCatInfo PBSetEOF PBSetFInfo PBSetFLock PBSetFPos PBSetFVers PBSetVInfo PBSetVol PBUnlockRange PBUnmountVol PBWrite Rename rstflock RstFLock SetEOF SetFInfo setfinfo setflock SetFLock SetFPos SetVol setvol unmountvol UnmountVol AccessParam alphaStage AltAccessParam AltAccessParamPtr betaStage CatPositionRec CInfoPBPtr CInfoPBRec CInfoType CMovePBPtr CMovePBRec CntrlParam CopyParam CSParam CSParamPtr developStage DInfo DirInfo dirInfo DrvQEl DrvQElPtr DTPBPtr DTPBRec DXInfo FCBPBPtr FCBPBRec fDesktop fDisk fHasBundle FIDParam FileParam finalStage FInfo fInvisible fOnDesk fsAtMark fsCurPerm fsFromLEOF fsFromMark fsFromStart fsRdPerm fsRdWrPerm fsRdWrShPerm fsRtDirID fsRtParID fsSBDrBkDat fsSBDrCrDat fsSBDrFndrInfo fsSBDrMdDat fsSBDrNmFls fsSBDrParID fsSBDrUsrWds fsSBFlAttrib fsSBFlBkDat fsSBFlCrDat fsSBFlFndrInfo fsSBFlLgLen fsSBFlMdDat fsSBFlParID fsSBFlPyLen fsSBFlRLgLen fsSBFlRPyLen fsSBFlXFndrInfo fsSBFullName fsSBNegate fsSBPartialName FSSpec FSSpecHandle FSSpecPtr fsWrPerm fTrash FXInfo HFileInfo hFileInfo HFileParam HIOParam HParamBlockRec HParmBlkPtr HVolumeParam ioDirFlg ioDirMask IOParam MultiDevParam NumVersion ObjParam ParamBlockHeader ParamBlockRec ParmBlkPtr rdVerify SlotDevParam VCB VersRec VersRecHndl VersRecPtr VolumeParam WDParam WDPBPtr WDPBRec æKY fsAtMark æFc Files.h æT #define æD /* Finder Constants */ #define fsAtMark 0 æC IOPosMode and ioPosOffset specify the position of the mark for Read, Write, LockRng, UnlockRng, and SetFPos calls. IOPosMode contains the positioning mode; bits 0 and 1 indicate how to position the mark, and you can use the following predefined constants to set or test their value: #define fsAtMark 0 /*at current mark*/ #define fsFromStart 1 /*set mark relative to beginning of file*/ #define fsFromLEOF 2 /*set mark relative to logical end-of-file*/ #define fsFromMark 3 /*set mark relative to current mark*/ If you specify fsAtMark, ioPosOffset is ignored and the operation begins wherever the mark is currently positioned. If you choose to set the mark (relative to either the beginning of the file, the logical end-of-file, or the current mark), ioPosOffset must specify the byte offset from the chosen point (either positive or negative) where the operation should begin. Note: Advanced programmers: Bit 7 of ioPosMode is the newline flag; it’s set if read operations should terminate at a newline character. The ASCII code of the newline character is specified in the high-order byte of ioPosMode. If the newline flag is set, the data will be read one byte at a time until the newline character is encountered, ioReqCount bytes have been read, or the end-of-file is reached. If the newline flag is clear, the data will be read one byte at a time until ioReqCount bytes have been read or the end-of-file is reached. æKY fOnDesk æFc Files.h æT #define æD #define fOnDesk 1 æC æKY fsCurPerm æFc Files.h æT #define æD #define fsCurPerm 0 æC IOPermssn requests permission to read or write via an access path, and must contain one of the following values: #define fsCurPerm 0 /*whatever is currently allowed*/ #define fsRdPerm 1 /*request for read permission only*/ #define fsWrPerm 2 /*request for write permission*/ #define fsRdWrPerm 3 /*request for exclusive read/write permission*/ #define fsRdWrShPerm 4 /*request for shared read/write permission*/ This request is compared with the open permission of the file. If the open permission doesn’t allow I/O as requested, a result code indicating the error is returned. Warning: To ensure data integrity be sure to lock the portion of the file you’ll be using if you specify shared write permission. æKY fHasBundle æFc Files.h æT #define æD #define fHasBundle 8192 æC æKY fsRdPerm æFc Files.h æT #define æD #define fsRdPerm 1 æC æKY fInvisible æFc Files.h æT #define æD #define fInvisible 16384 æC æKY fTrash æFc Files.h æT #define æD #define fTrash -3 æC æKY fsWrPerm æFc Files.h æT #define æD #define fsWrPerm 2 æC æKY fDesktop æFc Files.h æT #define æD #define fDesktop -2 æC æKY fsRdWrPerm æFc Files.h æT #define æD #define fsRdWrPerm 3 æC æKY fDisk æFc Files.h æT #define æD #define fDisk 0 æC æKY fsRdWrShPerm æFc Files.h æT #define æD #define fsRdWrShPerm 4 æC æKY fsFromStart æFc Files.h æT #define æD #define fsFromStart 1 æC æKY fsFromLEOF æFc Files.h æT #define æD #define fsFromLEOF 2 æC æKY fsFromMark æFc Files.h æT #define æD #define fsFromMark 3 æC æKY rdVerify æFc Files.h æT #define æD #define rdVerify 64 æC To have the File Manager verify that all data written to a volume exactly matches the data in memory, make a Read call right after the Write call. The parameters for a read-verify operation are the same as for a standard Read call, except that the following constant must be added to the positioning mode: #define rdVerify 64 /*read-verify mode*/ The result code ioErr is returned if any of the data doesn’t match. æKY ioDirFlg æFc Files.h æT #define æD #define ioDirFlg 3 æC æKY ioDirMask æFc Files.h æT #define æD #define ioDirMask 0x10 æC æKY fsRtParID æFc Files.h æT #define æD #define fsRtParID 1 æC æKY fsRtDirID æFc Files.h æT #define æD #define fsRtDirID 2 æC æKY fsSBNegate æFc Files.h æT #define æD #define fsSBNegate 16384 æC æKY fsSBPartialName æFc Files.h æT #define æD /* masks for SpecBits values */ #define fsSBPartialName 1 æC æKY fsSBFullName æFc Files.h æT #define æD #define fsSBFullName 2 æC æKY fsSBFlAttrib æFc Files.h æT #define æD #define fsSBFlAttrib 4 æC æKY fsSBFlFndrInfo æFc Files.h æT #define æD #define fsSBFlFndrInfo 8 æC æKY fsSBFlLgLen æFc Files.h æT #define æD #define fsSBFlLgLen 32 æC æKY fsSBFlPyLen æFc Files.h æT #define æD #define fsSBFlPyLen 64 æC æKY fsSBFlRLgLen æFc Files.h æT #define æD #define fsSBFlRLgLen 128 æC æKY fsSBFlRPyLen æFc Files.h æT #define æD #define fsSBFlRPyLen 256 æC æKY fsSBFlCrDat æFc Files.h æT #define æD #define fsSBFlCrDat 512 æC æKY fsSBFlMdDat æFc Files.h æT #define æD #define fsSBFlMdDat 1024 æC æKY fsSBFlBkDat æFc Files.h æT #define æD #define fsSBFlBkDat 2048 æC æKY fsSBFlXFndrInfo æFc Files.h æT #define æD #define fsSBFlXFndrInfo 4096 æC æKY fsSBFlParID æFc Files.h æT #define æD #define fsSBFlParID 8192 æC æKY fsSBDrUsrWds æFc Files.h æT #define æD #define fsSBDrUsrWds 8 æC æKY fsSBDrNmFls æFc Files.h æT #define æD #define fsSBDrNmFls 16 æC æKY fsSBDrCrDat æFc Files.h æT #define æD #define fsSBDrCrDat 512 æC æKY fsSBDrMdDat æFc Files.h æT #define æD #define fsSBDrMdDat 1024 æC æKY fsSBDrBkDat æFc Files.h æT #define æD #define fsSBDrBkDat 2048 æC æKY fsSBDrFndrInfo æFc Files.h æT #define æD #define fsSBDrFndrInfo 4096 æC æKY fsSBDrParID æFc Files.h æT #define æD #define fsSBDrParID 8192 æC æKY developStage æFc Files.h æT #define æD /* Version Release Stage Codes */ #define developStage 0x20 æC æKY alphaStage æFc Files.h æT #define æD #define alphaStage 0x40 æC æKY betaStage æFc Files.h æT #define æD #define betaStage 0x60 æC æKY finalStage æFc Files.h æT #define æD #define finalStage 0x80 æC æKY CInfoType hFileInfo dirInfo æFc Files.h æT enum æD enum {hFileInfo,dirInfo}; typedef unsigned char CInfoType; æC æKY FInfo æFc Files.h æT struct æD struct FInfo { OSType fdType; /*the type of the file*/ OSType fdCreator; /*file's creator*/ unsigned short fdFlags; /*flags ex. hasbundle,invisible,locked, etc.*/ Point fdLocation; /*file's location in folder*/ short fdFldr; /*folder containing file*/ }; typedef struct FInfo FInfo; æC æKY FXInfo æFc Files.h æT struct æD struct FXInfo { short fdIconID; /*Icon ID*/ short fdUnused[4]; /*unused but reserved 8 bytes*/ short fdComment; /*Comment ID*/ long fdPutAway; /*Home Dir ID*/ }; typedef struct FXInfo FXInfo; æC On hierarchical volumes, in addition to the FInfo record, the following information about files is maintained for the Finder: æKY DInfo æFc Files.h æT struct æD struct DInfo { Rect frRect; /*folder rect*/ unsigned short frFlags; /*Flags*/ Point frLocation; /*folder location*/ short frView; /*folder view*/ }; typedef struct DInfo DInfo; æC On hierarchical volumes, the following information about directories is maintained for the Finder: DInfo = RECORD frRect: Rect; {folder's rectangle} frFlags: INTEGER; {flags} frLocation: Point; {folder's location} frView: INTEGER; {folder's view} END; DXInfo = RECORD frScroll: Point; {scroll position} frOpenChain: LONGINT; {directory ID chain of open folders} frUnused: INTEGER; {reserved} frComment: INTEGER; {comment ID} frPutAway: LONGINT; {directory ID} END; When a file (or folder) is moved to the desktop on a hierarchical volume, it’s actually moved to the root level of the file directory. (This permits all the desktop icons to be enumerated by one simple scan of the root.) The fOnDesk bit of fdFlags is set. FDPutAway (or frPutAway for directories) contains the directory ID of the folder that originally contained the file (or folder); this allows the file (or folder) to be returned there from the desktop. æKY DXInfo æFc Files.h æT struct æD struct DXInfo { Point frScroll; /*scroll position*/ long frOpenChain; /*DirID chain of open folders*/ short frUnused; /*unused but reserved*/ short frComment; /*comment*/ long frPutAway; /*DirID*/ }; typedef struct DXInfo DXInfo; æC æKY ParamBlockHeader æFc Files.h æT struct æD #define ParamBlockHeader \ QElemPtr qLink; /*queue link in header*/ short qType; /*type byte for safety check*/ short ioTrap; /*FS: the Trap*/ Ptr ioCmdAddr; /*FS: address to dispatch to*/ ProcPtr ioCompletion; /*completion routine addr (0 for synch calls)*/ OSErr ioResult; /*result code*/ StringPtr ioNamePtr; /*ptr to Vol:FileName string*/ short ioVRefNum; /*volume refnum (DrvNum for Eject and MountVol)*/ æC æKY IOParam æFc Files.h æT struct æD struct IOParam { ParamBlockHeader short ioRefNum; /*refNum for I/O operation*/ char ioVersNum; /*version number*/ char ioPermssn; /*Open: permissions (byte)*/ Ptr ioMisc; /*Rename: new name (GetEOF,SetEOF: logical end of file) (Open: optional ptr to buffer) (SetFileType: new type)*/ Ptr ioBuffer; /*data buffer Ptr*/ long ioReqCount; /*requested byte count; also = ioNewDirID*/ long ioActCount; /*actual byte count completed*/ short ioPosMode; /*initial file positioning*/ long ioPosOffset; /*file position offset*/ }; typedef struct IOParam IOParam; æC æKY FileParam æFc Files.h æT struct æD struct FileParam { ParamBlockHeader short ioFRefNum; /*reference number*/ char ioFVersNum; /*version number*/ char filler1; short ioFDirIndex; /*GetFInfo directory index*/ unsigned char ioFlAttrib; /*GetFInfo: in-use bit=7, lock bit=0*/ unsigned char ioFlVersNum; /*file version number*/ FInfo ioFlFndrInfo; /*user info*/ unsigned long ioFlNum; /*GetFInfo: file number; TF- ioDirID*/ unsigned short ioFlStBlk; /*start file block (0 if none)*/ long ioFlLgLen; /*logical length (EOF)*/ long ioFlPyLen; /*physical length*/ unsigned short ioFlRStBlk; /*start block rsrc fork*/ long ioFlRLgLen; /*file logical length rsrc fork*/ long ioFlRPyLen; /*file physical length rsrc fork*/ unsigned long ioFlCrDat; /*file creation date& time (32 bits in secs)*/ unsigned long ioFlMdDat; /*last modified date and time*/ }; typedef struct FileParam FileParam; æC æKY VolumeParam æFc Files.h æT struct æD struct VolumeParam { ParamBlockHeader long filler2; short ioVolIndex; /*volume index number*/ unsigned long ioVCrDate; /*creation date and time*/ unsigned long ioVLsBkUp; /*last backup date and time*/ unsigned short ioVAtrb; /*volume attrib*/ unsigned short ioVNmFls; /*number of files in directory*/ unsigned short ioVDirSt; /*start block of file directory*/ short ioVBlLn; /*GetVolInfo: length of dir in blocks*/ unsigned short ioVNmAlBlks; /*GetVolInfo: num blks (of alloc size)*/ long ioVAlBlkSiz; /*GetVolInfo: alloc blk byte size*/ long ioVClpSiz; /*GetVolInfo: bytes to allocate at a time*/ unsigned short ioAlBlSt; /*starting disk(512-byte) block in block map*/ unsigned long ioVNxtFNum; /*GetVolInfo: next free file number*/ unsigned short ioVFrBlk; /*GetVolInfo: # free alloc blks for this vol*/ }; typedef struct VolumeParam VolumeParam; æC æKY CntrlParam æFc Files.h æT struct æD struct CntrlParam { QElem *qLink; /*queue link in header*/ short qType; /*type byte for safety check*/ short ioTrap; /*FS: the Trap*/ Ptr ioCmdAddr; /*FS: address to dispatch to*/ ProcPtr ioCompletion; /*completion routine addr (0 for synch calls)*/ OSErr ioResult; /*result code*/ StringPtr ioNamePtr; /*ptr to Vol:FileName string*/ short ioVRefNum; /*volume refnum (DrvNum for Eject and MountVol)*/ short ioCRefNum; /*refNum for I/O operation*/ short csCode; /*word for control status code*/ short csParam[11]; /*operation-defined parameters*/ }; typedef struct CntrlParam CntrlParam; æC æKY SlotDevParam æFc Files.h æT struct æD struct SlotDevParam { ParamBlockHeader short ioRefNum; char ioVersNum; char ioPermssn; Ptr ioMix; short ioFlags; char ioSlot; char ioID; }; typedef struct SlotDevParam SlotDevParam; æC æKY MultiDevParam æFc Files.h æT struct æD struct MultiDevParam { ParamBlockHeader short ioRefNum; char ioVersNum; char ioPermssn; Ptr ioMix; short ioFlags; Ptr ioSEBlkPtr; }; typedef struct MultiDevParam MultiDevParam; æC æKY ParamBlockRec ParmBlkPtr æFc Files.h æT struct æD union ParamBlockRec { IOParam ioParam; FileParam fileParam; VolumeParam volumeParam; CntrlParam cntrlParam; SlotDevParam slotDevParam; MultiDevParam multiDevParam; }; typedef union ParamBlockRec ParamBlockRec; typedef ParamBlockRec *ParmBlkPtr; æC »FileParam Variant ( ParamBlockRec and HParamBlockRec) The fileParam variants of ParamBlockRec and HParamBlockRec are identical, with one exception: The field ioDirID in HParamBlockRec is called ioFlNum in ParamBlockRec. The fields of the fileParam variant of HParamBlockRec are as follows: •••Refer to Technical Note #204:••• fileParam: (ioFRefNum: INTEGER; {path reference number} ioFVersNum: SignedByte; {version number} filler1: SignedByte; {not used} ioFDirIndex: INTEGER; {index} ioFlAttrib: SignedByte; {file attributes} ioFlVersNum: SignedByte; {version number} ioFlFndrInfo: FInfo; {information used by the Finder} ioDirID: LONGINT; {directory ID or file number} ioFlStBlk: INTEGER; {first allocation block of data fork} ioFlLgLen: LONGINT; {logical end-of-file of data fork} ioFlPyLen: LONGINT; {physical end-of-file of data fork} ioFlRStBlk: INTEGER; {first allocation block of resource fork} ioFlRLgLen: LONGINT; {logical end-of-file of resource fork} ioFlRPyLen: LONGINT; {physical end-of-file of resource fork} ioFlCrDat: LONGINT; {date and time of creation} ioFlMdDat: LONGINT); {date and time of last modification} IOFDirIndex can be used with the PBGetFInfo and PBHGetFInfo to index through the files in a given directory. Warning: When used with GetFileInfo, ioFDirIndex will index only the files in a directory. To index both files and directories, you can use ioFDirIndex with PBGetCatInfo. IOFlAttrib contains the following file attributes: Bit Meaning 0 Set if file is locked 2 Set if resource fork is open 3 Set if data fork is open 4 Set if a directory 7 Set if file (either fork) is open When passed to a routine, ioDirID contains a directory ID; it can be used to refer to a directory or, in conjuction with a partial pathname from that directory, to other files and directories. If both a directory ID and a working directory reference number are provided, the directory ID is used to identify the directory on the volume indicated by the working directory reference number. In other words, a directory ID specified by the caller will override the working directory referred to by the working directory reference number. If you don’t want this to happen, you can set ioDirID to 0. (If no directory is specified through a working directory reference number, the root directory ID will be used.) When returned from a routine, ioDirID contains the file number of a file; most programmers needn’t be concerned with file numbers, but those interested can read the section “Data Organization on Volumes”. IOFlStBlk and ioFlRStBlk contain 0 if the file’s data or resource fork is empty, respectively; they’re used only with flat volumes. The date and time in the ioFlCrDat and ioFlMdDat fields are specified in seconds since midnight, January 1, 1904. »VolumeParam Variant (ParamBlockRec) When you call GetVolInfo, you’ll use the volumeParam variant of ParamBlockRec: volumeParam: (filler2: LONGINT; {not used} ioVolIndex: INTEGER; {index} ioVCrDate: LONGINT; {date and time of initialization} ioVLsBkUp: LONGINT; {date and time of last modification} ioVAtrb: INTEGER; {volume attributes} ioVNmFls: INTEGER; {number of files in root directory} ioVDirSt: INTEGER; {first block of directory} ioVBlLn: INTEGER; {length of directory in blocks} ioVNmAlBlks: INTEGER; {number of allocation blocks} ioVAlBlkSiz: LONGINT; {size of allocation blocks} ioVClpSiz: LONGINT; {number of bytes to allocate} ioAlBlSt: INTEGER; {first block in volume block map} ioVNxtFNum: LONGINT; {next unused file number} ioVFrBlk: INTEGER); {number of unused allocation blocks} IOVolIndex can be used to index through all the mounted volumes; using an index of 1 accesses the first volume mounted, and so on. (For more information on indexing, see the section “Indexing” above.) IOVLsBkUp contains the date and time the volume information was last modified (this is not necessarily when it was flushed). (This field is not modified when information is written to a file.) Note: The name ioVLsBkUp is actually a misnomer; this field has always contained the date and time of the last modification to the volume, not the last backup. Most programmers needn’t be concerned with the remaining parameters, but interested programmers can read the section “Data Organization on Volumes”. »VolumeParam Variant (HParamBlockRec) When you call HGetVInfo and SetVolInfo, you’ll use the volumeParam variant of HParamBlockRec. This is a superset of the volumeParam variant of ParamBlockRec; the names and functions of certain fields have been changed, and new fields have been added: volumeParam: (filler2: LONGINT; {not used} ioVolIndex: INTEGER; {index} ioVCrDate: LONGINT; {date and time of initialization} ioVLsMod: LONGINT; {date and time of last modification} ioVAtrb: INTEGER; {volume attributes} ioVNmFls: INTEGER; {number of files in root directory} ioVBitMap: INTEGER; {first block of volume bit map} ioAllocPtr: INTEGER; {block at which next new file starts} ioVNmAlBlks: INTEGER; {number of allocation blocks} ioVAlBlkSiz: LONGINT; {size of allocation blocks} ioVClpSiz: LONGINT; {number of bytes to allocate} ioAlBlSt: INTEGER; {first block in volume block map} ioVNxtCNID: LONGINT; {next unused file number} ioVFrBlk: INTEGER; {number of unused allocation blocks} ioVSigWord: INTEGER; {volume signature} ioVDrvInfo: INTEGER; {drive number} ioVDRefNum: INTEGER; {driver reference number} ioVFSID: INTEGER; {file system handling this volume} ioVBkUp: LONGINT; {date and time of last backup} ioVSeqNum: INTEGER; {used internally} ioVWrCnt LONGINT; {volume write count} ioVFilCnt: LONGINT; {number of files on volume} ioVDirCnt: LONGINT; {number of directories on volume} ioVFndrInfo: ARRAY[1..8] OF LONGINT); {information used by the Finder} IOVolIndex can be used to index through all the mounted volumes; using an index of 1 accesses the first volume mounted, and so on. (For more information on indexing, see the section “Indexing” above.) IOVLsMod contains the date and time the volume information was last modified (this is not necessarily when it was flushed). (This field is not modified when information is written to a file.) Note: IOVLsMod replaces the field ioVLsBkUp in ParamBlockRec. The name ioVLsBkUp was actually a misnomer; this field has always contained the date and time of the last modification, not the last backup. Another field, ioVBkUp, contains the date and time of the last backup. IOVClpSiz can be used to set the volume clump size in bytes; it’s used for files that don’t have a clump size defined as part of their file information in the catalog. To promote file contiguity and avoid fragmentation, space is allocated to a file not in allocation blocks but in clumps. A clump is a group of contiguous allocation blocks. The clump size is always a multiple of the allocation block size; it’s the minimum number of bytes to allocate each time the Allocate function is called or the end-of-file is reached during the Write routine. IOVSigWord contains a signature word identifying the type of volume; it’s $D2D7 for flat directory volumes and $4244 for hierarchical directory volumes. The drive number of the drive containing the volume is returned in ioDrvInfo. For on-line volumes, ioVDRefNum returns the reference number of the I/O driver for the drive identified by ioDrvInfo. IOVFSID is the file-system identifier. It indicates which file system is servicing the volume; it’s 0 for File Manager volumes and nonzero for volumes handled by an external file system. IOVBkUp specifies the date and time the volume was last backed up (it’s 0 if never backed up). IOVNmFls contains the number of files in the root directory. IOVFilCnt contains the total number of files on the volume, while ioVDirCnt contains the total number of directories (not including the root directory). Most programmers needn’t be concerned with the other parameters, but interested programmers can read the section “Data Organization on Volumes”. HParamBlockRec, described above, has been extended to support a shared environment with the addition of AccessParam, ObjParam, CopyParam, and WDParam, as shown below. (The complete HParamBlockRec data type is shown in the summary.) AccessParam: (filler3: INTEGER; ioDenyModes: INTEGER; {access rights data} filler4: INTEGER; filler5: Signed Byte; ioACUser: Signed Byte; {access rights for directory only} filler6: LONGINT; ioACOwnerID: LONGINT; {owner ID} ioACGroupID: LONGINT; {group ID} ioACAccess: LONGINT); {access rights} ObjParam: (filler7: INTEGER; ioObjType: INTEGER; {function code} ioObjNamePtr: Ptr; {ptr to returned creator/group name} ioObjID: LONGINT; {creator/group ID} ioReqCount: LONGINT; {size of buffer area} ioActCount: LONGINT); {length of vol parms data} CopyParam: (ioDstVRefNum: INTEGER; {destination vol identifier} filler8: INTEGER; ioNewName: Ptr; {ptr to destination pathname} ioCopyName: Ptr; {ptr to optional name} ioNewDirID: LONGINT); {destination directory ID} WDParam: (filler9: INTEGER; ioWDIndex: INTEGER; ioWDProcID: LONGINT; ioWDVRefNum: INTEGER; filler10: INTEGER; filler11: LONGINT; filler12: LONGINT; filler13: LONGINT; ioWDDirID: LONGINT); æKY HFileInfo æFc Files.h æT struct æD struct HFileInfo { ParamBlockHeader short ioFRefNum; char ioFVersNum; char filler1; short ioFDirIndex; char ioFlAttrib; char filler2; FInfo ioFlFndrInfo; long ioDirID; unsigned short ioFlStBlk; long ioFlLgLen; long ioFlPyLen; unsigned short ioFlRStBlk; long ioFlRLgLen; long ioFlRPyLen; unsigned long ioFlCrDat; unsigned long ioFlMdDat; unsigned long ioFlBkDat; FXInfo ioFlXFndrInfo; long ioFlParID; long ioFlClpSiz; }; typedef struct HFileInfo HFileInfo; æC æKY DirInfo æFc Files.h æT struct æD struct DirInfo { ParamBlockHeader short ioFRefNum; short filler1; short ioFDirIndex; char ioFlAttrib; char filler2; DInfo ioDrUsrWds; long ioDrDirID; unsigned short ioDrNmFls; short filler3[9]; unsigned long ioDrCrDat; unsigned long ioDrMdDat; unsigned long ioDrBkDat; DXInfo ioDrFndrInfo; long ioDrParID; }; typedef struct DirInfo DirInfo; æC æKY CInfoPBRec CInfoPBPtr æFc Files.h æT struct æD union CInfoPBRec { HFileInfo hFileInfo; DirInfo dirInfo; }; typedef union CInfoPBRec CInfoPBRec; typedef CInfoPBRec *CInfoPBPtr; æC »CInfoPBRec The routines GetCatInfo and SetCatInfo are used for getting and setting information about the files and directories within a directory. With files, you’ll use the following 19 additional fields after the standard eight fields in the parameter block record CInfoPBRec: ioFRefNum: INTEGER; {path reference number} ioFVersNum: SignedByte; {version number} filler1: SignedByte; {not used} ioFDirIndex: INTEGER; {index} ioFlAttrib: SignedByte; {file attributes} filler2: SignedByte; {not used} hFileInfo: (ioFlFndrInfo: FInfo; {information used by the Finder} ioDirID: LONGINT; {directory ID or file number} ioFlStBlk: INTEGER; {first allocation block of data fork} ioFlLgLen: LONGINT; {logical end-of-file of data fork} ioFlPyLen: LONGINT; {physical end-of-file of data fork} ioFlRStBlk: INTEGER; {first allocation block of resource fork} ioFlRLgLen: LONGINT; {logical end-of-file of resource fork} ioFlRPyLen: LONGINT; {physical end-of-file of resource fork} ioFlCrDat: LONGINT; {date and time of creation} ioFlMdDat: LONGINT; {date and time of last modification} ioFlBkDat: LONGINT; {date and time of last backup} ioFlXFndrInfo: FXInfo; {additional information used by the Finder} ioFlParID: LONGINT; {file's parent directory ID (integer)} ioFlClpSiz: LONGINT); {file's clump size} •••Refer to Technical Note #69:••• IOFDirIndex can be used with the function PBGetCatInfo to index through the files and directories in a given directory. For each iteration of the function, you can determine whether it’s a file or a directory by testing bit 4 (the fifth least significant bit) of ioFlAttrib. You can test for a directory by using the Toolbox Utilities BitTst function in the following manner (remember, the Toolbox Utilities routines reverse the standard 68000 notation): BitTst(@myCInfoRec.ioFlAttrib,3) IOFlAttrib contains the following attributes: Bit Meaning 0 Set if file is locked 2 Set if resource fork is open 3 Set if data fork is open 4 Set if a directory 7 Set if file (either fork) is open When passed to a routine, ioDirID contains a directory ID; it can be used to refer to a directory or, in conjuction with a partial pathname from that directory, to other files and directories. If both a directory ID and a working directory reference number are provided, the directory ID is used to identify the directory on the volume indicated by the working directory reference number. In other words, a directory ID specified by the caller will override the working directory referred to by the working directory reference number. If you don’t want this to happen, you can set ioDirID to 0. (If no directory is specified through a working directory reference number, the root directory ID will be used.) Warning: With files, ioDirID returns the file number of the file; when indexing with GetCatInfo, you’ll need to reset this field for each iteration. IOFlStBlk and ioFlRStBlk contain 0 if the file’s data or resource fork is empty, respectively; they’re used only with flat volumes. The date and time in the ioFlCrDat, ioFlMdDat, and ioFlBkDat fields are specified in seconds since midnight, January 1, 1904. IOFlParID contains the directory ID of the file’s parent. IOFlClpSiz is the clump size to be used when writing the file; if it’s 0, the volume’s clump size is used when the file is opened. With directories, you’ll use the following 14 additional fields after the standard eight fields in the parameter block record CInfoPBRec: ioFRefNum: INTEGER; {file reference number} ioFVersNum SignedByte; {version number} filler1: SignedByte; {not used} ioFDirIndex: INTEGER; {index} ioFlAttrib: SignedByte; {file attributes} filler2: SignedByte; {not used} dirInfo: (ioDrUsrWds: DInfo; {information used by the Finder} ioDrDirID: LONGINT; {directory ID} ioDrNmFls: INTEGER; {number of files in directory} filler3: ARRAY[1..9] OF INTEGER; {not used} ioDrCrDat: LONGINT; {date and time of creation} ioDrMdDat: LONGINT; {date and time of last modification} ioDrBkDat: LONGINT; {date and time of last backup} ioDrFndrInfo: DXInfo; {additional information used by the Finder} ioDrParID: LONGINT); {directory's parent directory ID (integer)} IOFDirIndex can be used with the function PBGetCatInfo to index through the files and directories in a given directory. For each iteration of the function, you can determine whether it’s a file or a directory by testing bit 4 of ioFlAttrib. When passed to a routine, ioDrDirID contains a directory ID; it can be used to refer to a directory or, in conjuction with a partial pathname from that directory, to other files and directories. If both a directory ID and a working directory reference number are provided, the directory ID is used to identify the directory on the volume indicated by the working directory reference number. In other words, a directory ID specified by the caller will override the working directory referred to by the working directory reference number. If you don’t want this to happen, you can set ioDirID to 0. (If no directory is specified through a working directory reference number, the root directory ID will be used.) With directories, ioDrDirID returns the directory ID of the directory. IODrNmFls is the number of files and directories contained in this directory (the valence of the directory). The date and time in the ioDrCrDat, ioDrMdDat, and ioDrBkDat fields are specified in seconds since midnight, January 1, 1904. IODrParID contains the directory ID of the directory’s parent. æKY HIOParam æFc Files.h æT struct æD struct HIOParam { ParamBlockHeader short ioRefNum; char ioVersNum; char ioPermssn; Ptr ioMisc; Ptr ioBuffer; long ioReqCount; long ioActCount; short ioPosMode; long ioPosOffset; short filler1; }; typedef struct HIOParam HIOParam; æC æKY HFileParam æFc Files.h æT struct æD struct HFileParam { ParamBlockHeader short ioFRefNum; char ioFVersNum; char filler1; short ioFDirIndex; char ioFlAttrib; char ioFlVersNum; FInfo ioFlFndrInfo; long ioDirID; unsigned short ioFlStBlk; long ioFlLgLen; long ioFlPyLen; unsigned short ioFlRStBlk; long ioFlRLgLen; long ioFlRPyLen; unsigned long ioFlCrDat; unsigned long ioFlMdDat; }; typedef struct HFileParam HFileParam; æC æKY HVolumeParam æFc Files.h æT struct æD struct HVolumeParam { ParamBlockHeader long filler2; short ioVolIndex; unsigned long ioVCrDate; unsigned long ioVLsMod; short ioVAtrb; unsigned short ioVNmFls; short ioVBitMap; short ioAllocPtr; unsigned short ioVNmAlBlks; long ioVAlBlkSiz; long ioVClpSiz; short ioAlBlSt; long ioVNxtCNID; unsigned short ioVFrBlk; unsigned short ioVSigWord; short ioVDrvInfo; short ioVDRefNum; short ioVFSID; unsigned long ioVBkUp; unsigned short ioVSeqNum; long ioVWrCnt; long ioVFilCnt; long ioVDirCnt; long ioVFndrInfo[8]; }; typedef struct HVolumeParam HVolumeParam; æC æKY AccessParam æFc Files.h æT struct æD struct AccessParam { ParamBlockHeader short filler3; short ioDenyModes; /*access rights data*/ short filler4; char filler5; char ioACUser; /*access rights for directory only*/ long filler6; long ioACOwnerID; /*owner ID*/ long ioACGroupID; /*group ID*/ long ioACAccess; /*access rights*/ }; typedef struct AccessParam AccessParam; æC æKY ObjParam æFc Files.h æT struct æD struct ObjParam { ParamBlockHeader short filler7; short ioObjType; /*function code*/ Ptr ioObjNamePtr; /*ptr to returned creator/group name*/ long ioObjID; /*creator/group ID*/ long ioReqCount; /*size of buffer area*/ long ioActCount; /*length of vol parms data*/ }; typedef struct ObjParam ObjParam; æC æKY CopyParam æFc Files.h æT struct æD struct CopyParam { ParamBlockHeader short ioDstVRefNum; /*destination vol identifier*/ short filler8; Ptr ioNewName; /*ptr to destination pathname*/ Ptr ioCopyName; /*ptr to optional name*/ long ioNewDirID; /*destination directory ID*/ long filler14; long filler15; long ioDirID; /*same as in FileParam*/ }; typedef struct CopyParam CopyParam; æC æKY WDParam æFc Files.h æT struct æD struct WDParam { ParamBlockHeader short filler9; short ioWDIndex; long ioWDProcID; short ioWDVRefNum; short filler10; long filler11; long filler12; long filler13; long ioWDDirID; }; typedef struct WDParam WDParam; æC æKY FIDParam æFc Files.h æT struct æD struct FIDParam { ParamBlockHeader long filler1; Ptr ioDestNamePtr; /* dest file name */ long filler2; long ioDestDirID; /* dest file's directory id */ long filler3; long filler4; long ioSrcDirID; /* source file's directory id */ short filler5; long ioFileID; /* file ID */ }; typedef struct FIDParam FIDParam; /* Catalog position record */ æC æKY CatPositionRec æFc Files.h æT struct æD struct CatPositionRec { long initialize; short priv[6]; }; typedef struct CatPositionRec CatPositionRec; æC æKY FSSpec FSSpecPtr FSSpecHandle æFc Files.h æT struct æD struct FSSpec { short vRefNum; long parID; Str63 name; }; typedef struct FSSpec FSSpec; typedef FSSpec *FSSpecPtr, **FSSpecHandle; æC æKY CSParam CSParamPtr æFc Files.h æT struct æD struct CSParam { ParamBlockHeader FSSpecPtr ioMatchPtr; /* match array */ long ioReqMatchCount; /* maximum allowable matches */ long ioActMatchCount; /* actual match count */ long ioSpecBits; /* search criteria selector */ CInfoPBPtr ioSpec1; /* search values and range lower bounds */ CInfoPBPtr ioSpec2; /* search values and range upper bounds */ long ioSearchTime; /* length of time to run search */ CatPositionRec ioCatPosition; /* current position in the catalog */ Ptr ioOptBuffer; /* optional performance enhancement buffer */ long ioOptBufSize; /* size of buffer pointed to by ioOptBuffer */ }; typedef struct CSParam CSParam; typedef CSParam *CSParamPtr; æC æKY DTPBRec DTPBPtr æFc Files.h æT struct æD struct DTPBRec { ParamBlockHeader short ioDTRefNum; /* desktop refnum */ short ioIndex; long ioTagInfo; Ptr ioDTBuffer; long ioDTReqCount; long ioDTActCount; char ioFiller1; char ioIconType; short ioFiller2; long ioDirID; OSType ioFileCreator; OSType ioFileType; long ioFiller3; long ioDTLgLen; long ioDTPyLen; short ioFiller4[14]; long ioAPPLParID; }; typedef struct DTPBRec DTPBRec; typedef DTPBRec *DTPBPtr; æC æKY AltAccessParam AltAccessParamPtr æFc Files.h æT struct æD struct AltAccessParam { ParamBlockHeader long ioFiller1; long ioFiller2; Ptr ioAltAccessBuffer; long ioAltReqCount; long ioAltActCount; long ioAltAccessInfo1; long ioAltAccessInfo2; long ioAltAccessInfo3; long ioAltAccessInfo4; }; typedef struct AltAccessParam AltAccessParam; typedef AltAccessParam *AltAccessParamPtr; æC æKY HParamBlockRec HParmBlkPtr æFc Files.h æT struct æD union HParamBlockRec { HIOParam ioParam; HFileParam fileParam; HVolumeParam volumeParam; AccessParam accessParam; ObjParam objParam; CopyParam copyParam; WDParam wdParam; FIDParam fidParam; CSParam csParam; AltAccessParam altaccessParam; }; typedef union HParamBlockRec HParamBlockRec; typedef HParamBlockRec *HParmBlkPtr; æC »FileParam Variant ( ParamBlockRec and HParamBlockRec) The fileParam variants of ParamBlockRec and HParamBlockRec are identical, with one exception: The field ioDirID in HParamBlockRec is called ioFlNum in ParamBlockRec. The fields of the fileParam variant of HParamBlockRec are as follows: •••Refer to Technical Note #204:••• fileParam: (ioFRefNum: INTEGER; {path reference number} ioFVersNum: SignedByte; {version number} filler1: SignedByte; {not used} ioFDirIndex: INTEGER; {index} ioFlAttrib: SignedByte; {file attributes} ioFlVersNum: SignedByte; {version number} ioFlFndrInfo: FInfo; {information used by the Finder} ioDirID: LONGINT; {directory ID or file number} ioFlStBlk: INTEGER; {first allocation block of data fork} ioFlLgLen: LONGINT; {logical end-of-file of data fork} ioFlPyLen: LONGINT; {physical end-of-file of data fork} ioFlRStBlk: INTEGER; {first allocation block of resource fork} ioFlRLgLen: LONGINT; {logical end-of-file of resource fork} ioFlRPyLen: LONGINT; {physical end-of-file of resource fork} ioFlCrDat: LONGINT; {date and time of creation} ioFlMdDat: LONGINT); {date and time of last modification} IOFDirIndex can be used with the PBGetFInfo and PBHGetFInfo to index through the files in a given directory. Warning: When used with GetFileInfo, ioFDirIndex will index only the files in a directory. To index both files and directories, you can use ioFDirIndex with PBGetCatInfo. IOFlAttrib contains the following file attributes: Bit Meaning 0 Set if file is locked 2 Set if resource fork is open 3 Set if data fork is open 4 Set if a directory 7 Set if file (either fork) is open When passed to a routine, ioDirID contains a directory ID; it can be used to refer to a directory or, in conjuction with a partial pathname from that directory, to other files and directories. If both a directory ID and a working directory reference number are provided, the directory ID is used to identify the directory on the volume indicated by the working directory reference number. In other words, a directory ID specified by the caller will override the working directory referred to by the working directory reference number. If you don’t want this to happen, you can set ioDirID to 0. (If no directory is specified through a working directory reference number, the root directory ID will be used.) When returned from a routine, ioDirID contains the file number of a file; most programmers needn’t be concerned with file numbers, but those interested can read the section “Data Organization on Volumes”. IOFlStBlk and ioFlRStBlk contain 0 if the file’s data or resource fork is empty, respectively; they’re used only with flat volumes. The date and time in the ioFlCrDat and ioFlMdDat fields are specified in seconds since midnight, January 1, 1904. »VolumeParam Variant (ParamBlockRec) When you call GetVolInfo, you’ll use the volumeParam variant of ParamBlockRec: volumeParam: (filler2: LONGINT; {not used} ioVolIndex: INTEGER; {index} ioVCrDate: LONGINT; {date and time of initialization} ioVLsBkUp: LONGINT; {date and time of last modification} ioVAtrb: INTEGER; {volume attributes} ioVNmFls: INTEGER; {number of files in root directory} ioVDirSt: INTEGER; {first block of directory} ioVBlLn: INTEGER; {length of directory in blocks} ioVNmAlBlks: INTEGER; {number of allocation blocks} ioVAlBlkSiz: LONGINT; {size of allocation blocks} ioVClpSiz: LONGINT; {number of bytes to allocate} ioAlBlSt: INTEGER; {first block in volume block map} ioVNxtFNum: LONGINT; {next unused file number} ioVFrBlk: INTEGER); {number of unused allocation blocks} IOVolIndex can be used to index through all the mounted volumes; using an index of 1 accesses the first volume mounted, and so on. (For more information on indexing, see the section “Indexing” above.) IOVLsBkUp contains the date and time the volume information was last modified (this is not necessarily when it was flushed). (This field is not modified when information is written to a file.) Note: The name ioVLsBkUp is actually a misnomer; this field has always contained the date and time of the last modification to the volume, not the last backup. Most programmers needn’t be concerned with the remaining parameters, but interested programmers can read the section “Data Organization on Volumes”. »VolumeParam Variant (HParamBlockRec) When you call HGetVInfo and SetVolInfo, you’ll use the volumeParam variant of HParamBlockRec. This is a superset of the volumeParam variant of ParamBlockRec; the names and functions of certain fields have been changed, and new fields have been added: volumeParam: (filler2: LONGINT; {not used} ioVolIndex: INTEGER; {index} ioVCrDate: LONGINT; {date and time of initialization} ioVLsMod: LONGINT; {date and time of last modification} ioVAtrb: INTEGER; {volume attributes} ioVNmFls: INTEGER; {number of files in root directory} ioVBitMap: INTEGER; {first block of volume bit map} ioAllocPtr: INTEGER; {block at which next new file starts} ioVNmAlBlks: INTEGER; {number of allocation blocks} ioVAlBlkSiz: LONGINT; {size of allocation blocks} ioVClpSiz: LONGINT; {number of bytes to allocate} ioAlBlSt: INTEGER; {first block in volume block map} ioVNxtCNID: LONGINT; {next unused file number} ioVFrBlk: INTEGER; {number of unused allocation blocks} ioVSigWord: INTEGER; {volume signature} ioVDrvInfo: INTEGER; {drive number} ioVDRefNum: INTEGER; {driver reference number} ioVFSID: INTEGER; {file system handling this volume} ioVBkUp: LONGINT; {date and time of last backup} ioVSeqNum: INTEGER; {used internally} ioVWrCnt LONGINT; {volume write count} ioVFilCnt: LONGINT; {number of files on volume} ioVDirCnt: LONGINT; {number of directories on volume} ioVFndrInfo: ARRAY[1..8] OF LONGINT); {information used by the Finder} IOVolIndex can be used to index through all the mounted volumes; using an index of 1 accesses the first volume mounted, and so on. (For more information on indexing, see the section “Indexing” above.) IOVLsMod contains the date and time the volume information was last modified (this is not necessarily when it was flushed). (This field is not modified when information is written to a file.) Note: IOVLsMod replaces the field ioVLsBkUp in ParamBlockRec. The name ioVLsBkUp was actually a misnomer; this field has always contained the date and time of the last modification, not the last backup. Another field, ioVBkUp, contains the date and time of the last backup. IOVClpSiz can be used to set the volume clump size in bytes; it’s used for files that don’t have a clump size defined as part of their file information in the catalog. To promote file contiguity and avoid fragmentation, space is allocated to a file not in allocation blocks but in clumps. A clump is a group of contiguous allocation blocks. The clump size is always a multiple of the allocation block size; it’s the minimum number of bytes to allocate each time the Allocate function is called or the end-of-file is reached during the Write routine. IOVSigWord contains a signature word identifying the type of volume; it’s $D2D7 for flat directory volumes and $4244 for hierarchical directory volumes. The drive number of the drive containing the volume is returned in ioDrvInfo. For on-line volumes, ioVDRefNum returns the reference number of the I/O driver for the drive identified by ioDrvInfo. IOVFSID is the file-system identifier. It indicates which file system is servicing the volume; it’s 0 for File Manager volumes and nonzero for volumes handled by an external file system. IOVBkUp specifies the date and time the volume was last backed up (it’s 0 if never backed up). IOVNmFls contains the number of files in the root directory. IOVFilCnt contains the total number of files on the volume, while ioVDirCnt contains the total number of directories (not including the root directory). Most programmers needn’t be concerned with the other parameters, but interested programmers can read the section “Data Organization on Volumes”. HParamBlockRec, described above, has been extended to support a shared environment with the addition of AccessParam, ObjParam, CopyParam, and WDParam, as shown below. (The complete HParamBlockRec data type is shown in the summary.) AccessParam: (filler3: INTEGER; ioDenyModes: INTEGER; {access rights data} filler4: INTEGER; filler5: Signed Byte; ioACUser: Signed Byte; {access rights for directory only} filler6: LONGINT; ioACOwnerID: LONGINT; {owner ID} ioACGroupID: LONGINT; {group ID} ioACAccess: LONGINT); {access rights} ObjParam: (filler7: INTEGER; ioObjType: INTEGER; {function code} ioObjNamePtr: Ptr; {ptr to returned creator/group name} ioObjID: LONGINT; {creator/group ID} ioReqCount: LONGINT; {size of buffer area} ioActCount: LONGINT); {length of vol parms data} CopyParam: (ioDstVRefNum: INTEGER; {destination vol identifier} filler8: INTEGER; ioNewName: Ptr; {ptr to destination pathname} ioCopyName: Ptr; {ptr to optional name} ioNewDirID: LONGINT); {destination directory ID} WDParam: (filler9: INTEGER; ioWDIndex: INTEGER; ioWDProcID: LONGINT; ioWDVRefNum: INTEGER; filler10: INTEGER; filler11: LONGINT; filler12: LONGINT; filler13: LONGINT; ioWDDirID: LONGINT); æKY CMovePBRec CMovePBPtr æFc Files.h æT struct æD struct CMovePBRec { QElemPtr qLink; short qType; short ioTrap; Ptr ioCmdAddr; ProcPtr ioCompletion; OSErr ioResult; StringPtr ioNamePtr; short ioVRefNum; long filler1; StringPtr ioNewName; long filler2; long ioNewDirID; long filler3[2]; long ioDirID; }; typedef struct CMovePBRec CMovePBRec; typedef CMovePBRec *CMovePBPtr; æC »CMovePBRec When you call CatMove to move files or directories into a different directory, you’ll use the following six additional fields after the standard eight fields in the parameter block record CMovePBRec: filler1: LONGINT; {not used} ioNewName: StringPtr; {name of new directory} filler2: LONGINT; {not used} ioNewDirID: LONGINT; {directory ID of new directory} filler3: ARRAY[1..2] OF LONGINT; {not used} ioDirID: LONGINT); {directory ID of current directory} IONewName and ioNewDirID specify the name and directory ID of the directory to which the file or directory is to be moved. IODirID (used in conjuntion with the ioVRefNum and ioNamePtr) specifies the current directory ID of the file or directory to be moved. æKY WDPBRec WDPBPtr æFc Files.h æT struct æD struct WDPBRec { QElemPtr qLink; short qType; short ioTrap; Ptr ioCmdAddr; ProcPtr ioCompletion; OSErr ioResult; StringPtr ioNamePtr; short ioVRefNum; short filler1; short ioWDIndex; long ioWDProcID; short ioWDVRefNum; short filler2[7]; long ioWDDirID; }; typedef struct WDPBRec WDPBRec; typedef WDPBRec *WDPBPtr; æC »WDPBRec When you call the routines that open, close, and get information about working directories, you’ll use the following six additional fields after the standard eight fields in the parameter block record WDPBRec: filler1: INTEGER; {not used} ioWDIndex: INTEGER; {index} ioWDProcID: LONGINT; {working directory user identifier} ioWDVRefNum: INTEGER; {working directory's volume reference number} filler2: ARRAY[1..7] OF INTEGER; {not used} ioWDDirID: LONGINT); {working directory's directory ID} IOWDIndex can be used with the function PBGetWDInfo to index through the current working directories. IOWDProcID is an identifier that’s used to distinguish between working directories set up by different users; you should use the application’s signature (discussed in the Finder Interface chapter) as the ioWDProcID. æKY FCBPBRec FCBPBPtr æFc Files.h æT struct æD struct FCBPBRec { QElemPtr qLink; short qType; short ioTrap; Ptr ioCmdAddr; ProcPtr ioCompletion; OSErr ioResult; StringPtr ioNamePtr; short ioVRefNum; short ioRefNum; short filler; short ioFCBIndx; short filler1; long ioFCBFlNm; short ioFCBFlags; unsigned short ioFCBStBlk; long ioFCBEOF; long ioFCBPLen; long ioFCBCrPs; short ioFCBVRefNum; long ioFCBClpSiz; long ioFCBParID; }; typedef struct FCBPBRec FCBPBRec; typedef FCBPBRec *FCBPBPtr; æC æKY VCB æFc Files.h æT struct æD struct VCB { QElemPtr qLink; short qType; short vcbFlags; unsigned short vcbSigWord; unsigned long vcbCrDate; unsigned long vcbLsMod; short vcbAtrb; unsigned short vcbNmFls; short vcbVBMSt; short vcbAllocPtr; unsigned short vcbNmAlBlks; long vcbAlBlkSiz; long vcbClpSiz; short vcbAlBlSt; long vcbNxtCNID; unsigned short vcbFreeBks; Str27 vcbVN; short vcbDrvNum; short vcbDRefNum; short vcbFSID; short vcbVRefNum; Ptr vcbMAdr; Ptr vcbBufAdr; short vcbMLen; short vcbDirIndex; short vcbDirBlk; unsigned long vcbVolBkUp; unsigned short vcbVSeqNum; long vcbWrCnt; long vcbXTClpSiz; long vcbCTClpSiz; unsigned short vcbNmRtDirs; long vcbFilCnt; long vcbDirCnt; long vcbFndrInfo[8]; unsigned short vcbVCSize; unsigned short vcbVBMCSiz; unsigned short vcbCtlCSiz; unsigned short vcbXTAlBlks; unsigned short vcbCTAlBlks; short vcbXTRef; short vcbCTRef; Ptr vcbCtlBuf; long vcbDirIDM; short vcbOffsM; }; typedef struct VCB VCB; æC »Volume Control Blocks •••Refer to Technical Note #106:••• Each time a volume is mounted, its volume information is read from it and is used to build a new volume control block in the volume-control-block queue (unless an ejected or off-line volume is being remounted). A copy of the volume block map is also read from the volume and placed in the system heap, and a volume buffer is created in the system heap. The volume-control-block queue is a standard Operating System queue that’s maintained in the system heap. It contains a volume control block for each mounted volume. A volume control block is a 178-byte nonrelocatable block that contains volume-specific information. It has the following structure: TYPE VCB = RECORD qLink: QElemPtr; {next queue entry} qType: INTEGER; {queue type} vcbFlags: INTEGER; {bit 15=1 if dirty} vcbSigWord: INTEGER; {$4244 for hierarchical, $D2D7 for flat} vcbCrDate: LONGINT; {date and time of initialization} vcbLsMod: LONGINT; {date and time of last modification} vcbAtrb: INTEGER; {volume attributes} vcbNmFls: INTEGER; {number of files in directory} vcbVBMSt: INTEGER; {first block of volume bit map} vcbAllocPtr: INTEGER; {used internally} vcbNmAlBlks: INTEGER; {number of allocation blocks} vcbAlBlkSiz: LONGINT; {allocation block size} vcbClpSiz: LONGINT; {default clump size} vcbAlBlSt: INTEGER; {first block in block map} vcbNxtCNID: LONGINT; {next unused directory ID or file number} vcbFreeBks: INTEGER; {number of unused allocation blocks} vcbVN: STRING[27]; {volume name} vcbDrvNum: INTEGER; {drive number} vcbDRefNum: INTEGER; {driver reference number} vcbFSID: INTEGER; {file-system identifier} vcbVRefNum: INTEGER; {volume reference number} vcbMAdr: Ptr; {pointer to block map} vcbBufAdr: Ptr; {pointer to volume buffer} vcbMLen: INTEGER; {number of bytes in block map} vcbDirIndex: INTEGER; {used internally} vcbDirBlk: INTEGER; {used internally} vcbVolBkUp: LONGINT; {date and time of last backup} vcbVSeqNum: INTEGER; {used internally} vcbWrCnt: LONGINT; {volume write count} vcbXTClpSiz: LONGINT; {clump size of extents tree file} vcbCTClpSiz: LONGINT; {clump size of catalog tree file} vcbNmRtDirs: INTEGER; {number of directories in root} vcbFilCnt: LONGINT; {number of files on volume} vcbDirCnt: LONGINT; {number of directories on volume} vcbFndrInfo: ARRAY[1..8] OF LONGINT; {information used by } { the Finder} vcbVCSize: INTEGER; {used internally} vcbVBMCSiz: INTEGER; {used internally} vcbCtlCSiz: INTEGER; {used internally} vcbXTAlBks: INTEGER; {size in blocks of extents tree file} vcbCTAlBks: INTEGER; {size in blocks of catalog tree file} vcbXTRef: INTEGER; {path reference number for extents } { tree file} vcbCTRef: INTEGER; {path reference number for catalog } { tree file} vcbCtlBuf: Ptr; {pointer to extents and catalog } { tree caches} vcbDirIDM: LONGINT; {directory last searched} vcbOffsM: INTEGER {offspring index at last search} END; 64K ROM note: A volume control block created for a flat volume is a subset of the above structure. It’s actually smaller and contains only the fields up to and including vcbDirBlk. In addition, the names of several fields have been changed to reflect the fact that they contain different information on hierarchical volumes: vcbLsBkUp, vcbDirSt, vcbBlLn, vcbNmBlks, and vcbNxtFNum have been changed to vcbLsMod, vcbVBMSt, vcbAllocPtr, vcbNmAlBlks, and vcbNxtCNID respectively. QLink points to the next entry in the queue, and qType indicates the queue type, which must always be ORD(fsQType). Bit 15 of vcbFlags is set if the volume information has been changed by a routine call since the volume was last affected by a FlushVol call. VCBLsMod contains the date and time that the volume was last modified (this is not necessarily when it was flushed). 64K ROM note: VCBLsMod replaces the field vcbLsBkUp from flat directory volumes. The name vcbLsBkUp was actually a misnomer; this field has always contained the date and time of the last modification, not the last backup. Another field, vcbVolBkUp, contains the date and time of the last backup. VCBAtrb contains the volume attributes, as follows: Bit Meaning 0–4 Set if inconsistencies were found between the volume information and the file directory when the volume was mounted 6 Set if volume is busy (one or more files are open) 7 Set if volume is locked by hardware 15 Set if volume is locked by software VCBVBMSt contains the number of the first block in the volume bit map; on flat volumes, it contains the first block of the file directory. VCBNmAlBlks contains the number of allocation blocks on the volume, and vcbFreeBks specifies how many of those blocks are unused. VCBAlBlSt is used only with flat volumes; it contains the number of the first block in the block map. VCBDrvNum contains the drive number of the drive on which the volume is mounted; vcbDRefNum contains the driver reference number of the driver used to access the volume. When a mounted volume is placed off-line, vcbDrvNum is cleared. When a volume is ejected, vcbDrvNum is cleared and vcbDRefNum is set to the negative of vcbDrvNum (becoming a positive number). VCBFSID identifies the file system handling the volume; it’s 0 for volumes handled by the File Manager, and nonzero for volumes handled by other file systems. When a volume is placed off-line, its buffer and bit map (or block map, in the case of flat directory volumes) are released. When a volume is unmounted, its volume control block is removed from the volume-control-block queue. You can get a pointer to the header of the volume-control-block queue by calling the File Manager function GetVCBQHdr. æKY DrvQEl DrvQElPtr æFc Files.h æT struct æD struct DrvQEl { QElemPtr qLink; short qType; short dQDrive; short dQRefNum; short dQFSID; unsigned short dQDrvSz; unsigned short dQDrvSz2; }; typedef struct DrvQEl DrvQEl; typedef DrvQEl *DrvQElPtr; æC »The Drive Queue •••Refer to Technical Note #36:••• Disk drives connected to the Macintosh are opened when the system starts up, and information describing each is placed in the drive queue. This is a standard Operating System queue, and each entry in it has the following structure: TYPE DrvQEl = RECORD qLink: QElemPtr; {next queue entry} qType: INTEGER; {queue type} dQDrive: INTEGER; {drive number} dQRefNum: INTEGER; {driver reference number} dQFSID: INTEGER; {file-system identifier} dQDrvSz: INTEGER; {number of logical blocks on drive} dQDrvSz2: INTEGER; {additional field to handle large } { drive size} END; QLink points to the next entry in the queue. If qType is 0, this means the number of logical blocks on the drive is contained in the dQDrvSz field alone. If qType is 1, both dQDrvSz and dQDrvSz2 are used to store the number of blocks; dqDrvSz2 contains the high-order word of this number and dQDrvSz contains the low-order word. DQDrive contains the drive number of the drive on which the volume is mounted; dQRefNum contains the driver reference number of the driver controlling the device on which the volume is mounted. DQFSID identifies the file system handling the volume in the drive; it’s 0 for volumes handled by the File Manager, and nonzero for volumes handled by other file systems. Four bytes of flags precede each drive queue entry; they’re accessible only from assembly language. Assembly-language note: These bytes contain the following: Byte Contents 0 Bit 7=1 if volume is locked 1 0 if no disk in drive; 1 or 2 if disk in drive; 8 if nonejectable disk in drive; $FC-$FF if disk was ejected within last 1.5 seconds; $48 if disk in drive is nonejectable but driver wants a call 2 Used internally during system startup 3 Bit 7=0 if disk is single-sided You can get a pointer to the header of the drive queue by calling the File Manager function GetDrvQHdr. æKY NumVersion æFc Files.h æT struct æD struct NumVersion { unsigned char majorRev; /*1st part of version number in BCD*/ unsigned int minorRev : 4; /*2nd part is 1 nibble in BCD*/ unsigned int bugFixRev : 4; /*3rd part is 1 nibble in BCD*/ unsigned char stage; /*stage code: dev, alpha, beta, final*/ unsigned char nonRelRev; /*revision level of non-released version*/ }; typedef struct NumVersion NumVersion; /* Numeric version part of 'vers' resource */ æC æKY VersRec VersRecPtr VersRecHndl æFc Files.h æT struct æD struct VersRec { NumVersion numericVersion; /*encoded version number*/ short countryCode; /*country code from intl utilities*/ Str255 shortVersion; /*version number string - worst case*/ Str255 reserved; /*longMessage string packed after shortVersion*/ }; typedef struct VersRec VersRec; typedef VersRec *VersRecPtr, **VersRecHndl; /* 'vers' resource format */ æC æKY PBHGetVolParms æFc Files.h æT Function æD pascal OSErr PBHGetVolParms(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHGetVolParms((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-392, VI æC Trap macro _GetVolParms Parameter block Æ 12 ioCompletion long pointer to completion routine ¨ 16 ioResult word error result code Æ 18 ioFileName long volume name specifier Æ 22 ioVRefNum word volume refNum ¨ 32 ioBuffer long pointer to attributes buffer Æ 36 ioReqCount long size of buffer area ¨ 40 ioActCount long length of volume parms data <See the description in Volume V. We have a new version of the attributes buffer and new values for vMAttrib:> Attributes buffer 0 vMVersion word version number (02 for this version) 2 vMAttrib long attributes (detailed below) 6 vMLocalHand long handle to private data for shared volumes 10 vMServerAdr long AppleTalk server address (0 if not supported) 14 vMVolumeGrade long Approximate speed rating of volume 18 vMAltPrivModel word Alternative privilege model supported (two values currently defined: 0 for an HFS volume; 1 for an A/UX volume) Bit positions in vMAttrib 31 bLimitFCBs Limit the number of FCBs used during copying to 8 instead of 16. 30 bLocalWList Use the returned shared volume handle for the Finder’s local window list. 29 bNoMiniFndr Disable Mini Finder menu item. 28 bNoVNEdit Lock volume name against editing. 27 bNoLclSync Do not let Finder change the modification date. 26 bTrshOffLine Zoom volume when it goes off line to the Trash and when it’s unmounted. 25 bNoSwitchTo Do not switch-launch to any application on the volume. 24-21 Reserved. Server volumes return these bits set. All other volumes return these bits cleared. 20 bNoDeskItems Do not place objects on the Finder desktop. 19 bNoBootBlks Not a startup volume. Startup menu item disabled. Bootblocks not copied. 18 bAccessCntl Volume supports AppleTalk AFP access control interfaces. The functions GetLoginInfo, GetDirAccess, SetDirAccess, MapID, and MapName are supported. Special folder icons are used. Access Privileges menu item is enabled for disk and folder items. The privileges field of GetCatInfo calls are assumed to be valid. 17 bNoSysDir Volume doesn’t support a system directory. Do not switch launch to this volume. 16 bExtFSVol Volume is an external file system volume. Disk initialization package is not called. Erase Disk menu item is disabled. 15 bHasOpenDeny Volume supports _OpenDeny and _OpenRFDeny. For copy operations, source files are opened with enable read/deny write and destination files are opened enable write/deny read and write. 14 bHasCopyFile Volume supports _CopyFile. _CopyFile is used in copy and duplicate operations if both source and destination volumes have same server address. 13 bHasMoveRename Volume supports _MoveRename. 12 bHasNewDesk Volume supports all of the new desktop functions (described in Volume V). 11 bHasShortName Volume supports a name that fits the requirements of another file system. 10 bHasFolderLock Folder is locked. 9 bHasPersonalAccessPrivileges Macintosh File Share is running. 8 bHasUserGroupList Volume supports the Users and Groups file and thus the AFP privilege functions. 7 bHasCatSearch Volume supports PBCatSearch. 6 bHasFileIDs Volume supports fileID functions 5 For internal use only 4-0 Reserved. All volumes return these bits clear. æKY PBHGetLogInInfo æFc Files.h æT Function æD pascal OSErr PBHGetLogInInfo(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHGetLogInInfo((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-393 æC Trap macro _GetLogInInfo Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 22 ioVRefNum word volume refNum <-- 26 ioObjType word log in method <-- 28 ioObjNamePtr long ptr to log in name buffer PBHGetLogInInfo returns the method used for log-in and the user name specified at log-in time for the volume. The log-in user name is returned as a Pascal string in ioObjNamePtr. The maximum size of the user name is 31 characters. The log-in method type is returned in ioObjType. æKY PBHGetDirAccess æFc Files.h æT Function æD pascal OSErr PBHGetDirAccess(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHGetDirAccess((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-394 æC Trap macro _GetDirAccess Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long directory name --> 22 ioVRefNum word volume refNum <-- 36 ioACOwnerID long owner ID <-- 40 ioACGroupID long group ID <-- 44 ioACAccess long access rights --> 48 ioDirID long directory ID PBHGetDirAccess returns access control information for the folder pointed to by the ioDirID/ioFIleName pair. ioACOwnerID will return the ID for the folder’s owner. ioACGroupID will return the ID for the folder’s primary group. The access rights are returned in ioACAccess. A fnfErr is returned if the pathname does not point to a valid directory. An AccessDenied error is returned if the user does not have the correct access rights to examine this directory. æKY PBHSetDirAccess æFc Files.h æT Function æD pascal OSErr PBHSetDirAccess(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHSetDirAccess((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-394 æC Trap macro _SetDirAccess Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long pathname identifier --> 22 ioVRefNum word volume refNum --> 36 ioACOwnerID long owner ID --> 40 ioACGroupID long group ID --> 44 ioACAccess long access rights --> 48 ioDirID long directory ID PBHSetDirAccess allows you to change the access rights to a folder pointed to by the ioFileName/ioDirID pair. IOACOwnerID contains the new owner ID. IOACGroupID contains the group ID. IOACAccess contains the folder’s access rights. You cannot set the owner bit or the user’s rights of the directory. To change the owner or group, you should set the ioACOwnerID or ioACGroupID field with the appropriate ID of the new owner/group. You must be the owner of the directory to change the owner or group ID. A fnfErr is returned if the pathname does not point to a valid directory. An AccessDenied error is returned if you do not have the correct access rights to modify the parameters for this directory. A paramErr is returned if you try to set the owner bit or user’s rights bits. æKY PBHMapID æFc Files.h æT Function æD pascal OSErr PBHMapID(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHMapID((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-395 æC Trap macro _MapID Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long pathname identifier --> 22 ioVRefNum word volume refNum --> 26 ioObjType word function code <-- 28 ioObjNamePtr long ptr to retrnd creator/group name --> 32 ioObjID long creator/group ID PBHMapID returns the name of a user or group given its unique ID. IOObjID contains the ID to be mapped. The value zero for ioObjID is special cased and will always return a NIL name. AppleShare uses this to signify <Any User>. IOObjType is the mapping function code; it’s 1 if you’re mapping an owner ID to owner name or 2 if you’re mapping a group ID to a group name. The name is returned as a Pascal string in ioObjNamePtr. The maximum size of the name is 31 characters. A fnfErr is returned if an unrecognizable owner or group ID is passed. æKY PBHMapName æFc Files.h æT Function æD pascal OSErr PBHMapName(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHMapName((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-395 æC Trap macro _MapName Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long volume identifier (may be NIL) --> 22 ioVRefNum word volume refNum --> 28 ioObjNamePtr long owner or group name --> 26 ioObjType word function code <-- 32 ioObjID long creator/group ID PBHMapName returns the unique user ID or group ID given its name. The name is passed as a string in ioObjNamePtr. If a NIL name is passed, the ID returned will always be zero. The maximum size of the name is 31 characters. IOObjType is the mapping function code; it’s 3 if you’re mapping an owner name to owner ID or 4 if you’re mapping a group name to a group ID. IOObjID will contain the mapped ID. A fnfErr is returned if an unrecognizable owner or group name is passed. æKY PBHCopyFile æFc Files.h æT Function æD pascal OSErr PBHCopyFile(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHCopyFile((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-396 æC Trap macro _CopyFile Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long ptr to source pathname --> 22 ioVRefNum word source vol identifier --> 24 ioDstVRefNum word destination vol identifier --> 28 ioNewName long ptr to destination pathname --> 32 ioCopyName long ptr to optional name (may be NIL) --> 36 ioNewDirID long destination directory ID --> 48 ioDirID long source directory ID PBHCopyFile duplicates a file on the volume and optionally renames it. It is an optional call for AppleShare file servers. You should examine the returned flag information in the PBHGetVolParms call to see if this volume supports CopyFile. For AppleShare file servers, the source and destination pathnames must indicate the same file server; however, it may point to a different volume for that file server. A useful way to tell if two file server volumes are on the same file server is to make the GetVolParms call and compare the server addresses returned. The server will open source files with read/deny write enabled and destination files with write/deny read and write enabled. IOVRefNum contains a source volume identifier. The source pathname is determined by the ioFileName/ioDirID pair. IODstVRefNum contains a destination volume identifier. AppleShare 1.0 required that it be an actual volume reference number; however, on future versions it can be a WDRefNum. The destination pathname is determined by the ioNewName/ioNewDirID pair. IOCopyName may contain an optional string used in renaming the file. If it is non-NIL then the file copy will be renamed to the specified name in ioCopyName. A fnfErr is returned if the source pathname does not point to an existing file or the destination pathname does not point to an existing directory. An AccessDenied error is returned if the user does not have the right to read the source or write to the destination. A dupFnErr is returned if the destination already exists. A DenyConflict error is returned if either the source or destination file could not be opened under the access modes described above. æKY PBHMoveRename æFc Files.h æT Function æD pascal OSErr PBHMoveRename(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHMoveRename((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-397 æC Trap macro _MoveRename Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long ptr to source pathname --> 22 ioVRefNum word source vol identifier --> 28 ioNewName long ptr to destination pathname --> 32 ioBuffer long ptr to optional name (may be NIL) --> 36 ioNewDirID long destination directory ID --> 48 ioDirID long source directory ID PBHMoveRename allows you to move (not copy) an item and optionally to rename it. The source and destination pathnames must point to the same file server volume. IOVRefNum contains a source volume identifier. The source pathname is specified by the ioFileName/ioDirID pair. The destination pathname is specified by the ioNewName/ioNewDirID pair. IOBuffer may contain an optional string used in renaming the item. If it is non-NIL then the moved object will be renamed to the specified name in ioBuffer. A fnfErr is returned if the source pathname does not point to an existing object. An AccessDenied error is returned if the user does not have the right to move the object. A dupFnErr is returned if the destination already exists. A badMovErr is returned if an attempt is made to move a directory into one of its descendent directories. æKY PBHOpenDeny æFc Files.h æT Function æD pascal OSErr PBHOpenDeny(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHOpenDeny((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-398 æC Trap macro _OpenDeny Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long ptr to pathname --> 22 ioVRefNum word vol identifier <-- 24 ioRefNum word file refNum --> 26 ioDenyModes word access rights data --> 48 ioDirID long directory ID PBHOpenDeny opens a file’s data fork under specific access rights. It creates an access path to the file having the name pointed to by ioFileName/ioDirID. The path reference number is returned in ioRefNum. IODenyModes contains a word of access rights information. The format for these access rights is: bits 15–6 Reserved—should be cleared. 5 If set, other writers are denied access. 4 If set, other readers are denied access. 3–2 Reserved—should be cleared. 1 If set, write permission requested. 0 If set, read permission requested. A fnfErr is returned if the input specification does not point to an existing file. A permErr is returned if the file is already open and you cannot open it under the deny modes that you have specified. An opWrErr is returned if you have asked for write permission and the file is already opened by you for write. The already opened path reference number is returned in ioRefNum. An AccessDenied error is returned if you do not have the right to access the file. æKY PBHOpenRFDeny æFc Files.h æT Function æD pascal OSErr PBHOpenRFDeny(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHOpenRFDeny((HParmBlkPtr) paramBlock,(Boolean) async); æRI V-398 æC Trap macro _OpenRFDeny Parameter block --> 12 ioCompletion long optional completion routine ptr <-- 16 ioResult word error result code --> 18 ioFileName long ptr to pathname --> 22 ioVRefNum word vol identifier <-- 24 ioRefNum word file refNum --> 26 ioDenyModes word access rights data --> 48 ioDirID long directory ID PBHOpenRFDeny opens a file’s resource fork under specific access rights. It creates an access path to the file having the name pointed to by ioFileName/ioDirID. The path reference number is returned in ioRefNum. The format of the access rights data contained in ioDenyModes is described under the OpenDeny call. A fnfErr is returned if the input specification does not point to an existing file. A permErr is returned if the file is already open and you cannot open it under the deny modes that you have specified. An opWrErr is returned if you have asked for write permission and the file is already opened by you for write. The already-opened path reference number is returned in ioRefNum. An AccessDenied error is returned if you do not have the right to access the file. æKY PBOpen æFc Files.h æT Function æD pascal OSErr PBOpen(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBOpen((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-108 æC Trap macro _Open Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word <-- 24 ioRefNum word --> 26 ioVersNum byte --> 27 ioPermssn byte --> 28 ioMisc pointer PBOpen creates an access path to the file having the name pointed to by ioNamePtr (and on flat volumes, the version number ioVersNum) on the volume specified by ioVRefNum. A path reference number is returned in ioRefNum. IOMisc either points to a portion of memory (522 bytes) to be used as the access path’s buffer, or is NIL if you want the volume buffer to be used instead. Warning: All access paths to a single file that’s opened multiple times should share the same buffer so that they will read and write the same data. IOPermssn specifies the path’s read/write permission. A path can be opened for writing even if it accesses a file on a locked volume, and an error won’t be returned until a PBWrite, PBSetEOF, or PBAllocate call is made. If you attempt to open a locked file for writing, PBOpen will return permErr as its function result. If you request exclusive read/write permission but another access path already has write permission (whether write only, exclusive read/write, or shared read/write), PBOpen will return the reference number of the existing access path in ioRefNum and opWrErr as its function result. Similarly, if you request shared read/write permission but another access path already has exclusive read/write permission, PBOpen will return the reference number of the access path in ioRefNum and opWrErr as its function result. Result codes noErr No error bdNamErr Bad file name extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing permErr Attempt to open locked file for writing tmfoErr Too many files open æKY PBClose æFc Files.h æT Function æD pascal OSErr PBClose(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBClose((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-114 æC Trap macro _Close Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word PBClose writes the contents of the access path buffer specified by ioRefNum to the volume and removes the access path. Warning: Some information stored on the volume won’t be correct until PBFlushVol is called. Result codes noErr No error extFSErr External file system fnfErr File not found fnOpnErr File not open ioErr I/O error nsvErr No such volume rfNumErr Bad reference number æKY PBRead æFc Files.h æT Function æD pascal OSErr PBRead(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBRead((ParmBlkPtr) paramBlock,(Boolean) async); æRT 187 æRI II-110 æC Trap macro _Read Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 32 ioBuffer pointer --> 36 ioReqCount long word <-- 40 ioActCount long word --> 44 ioPosMode word <-> 46 ioPosOffset long word PBRead attempts to read ioReqCount bytes from the open file whose access path is specified by ioRefNum, and transfer them to the data buffer pointed to by ioBuffer. The position of the mark is specified by ioPosMode and ioPosOffset. If you try to read past the logical end-of-file, PBRead moves the mark to the end-of-file and returns eofErr as its function result. After the read is completed, the mark is returned in ioPosOffset and the number of bytes actually read is returned in ioActCount. Result codes noErr No error eofErr End-of-file extFSErr External file system fnOpnErr File not open ioErr I/O error paramErr Negative ioReqCount rfNumErr Bad reference number æKY PBWrite æFc Files.h æT Function æD pascal OSErr PBWrite(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBWrite((ParmBlkPtr) paramBlock,(Boolean) async); æRT 187 æRI II-110 æC •••Refer to Technical Note #187:••• Trap macro _Write Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 32 ioBuffer pointer --> 36 ioReqCount long word <-- 40 ioActCount long word --> 44 ioPosMode word <-> 46 ioPosOffset long word PBWrite takes ioReqCount bytes from the buffer pointed to by ioBuffer and attempts to write them to the open file whose access path is specified by ioRefNum. The position of the mark is specified by ioPosMode and ioPosOffset. After the write is completed, the mark is returned in ioPosOffset and the number of bytes actually written is returned in ioActCount. Result codes noErr No error dskFulErr Disk full fLckdErr File locked fnOpnErr File not open ioErr I/O error paramErr Negative ioReqCount posErr Attempt to position before start of file rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing æKY PBGetVInfo æFc Files.h æT Function æD pascal OSErr PBGetVInfo(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetVInfo((ParmBlkPtr) paramBlock,(Boolean) async); æRT 24, 44, 157 æRI II-104, IV-129, N24-1, N44-2, N157 æC Trap macro _GetVolInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-> 18 ioNamePtr pointer <-> 22 ioVRefNum word --> 28 ioVolIndex word <-- 30 ioVCrDate long word <-- 34 ioVLsBkUp long word <-- 38 ioVAtrb word <-- 40 ioVNmFls word <-- 42 ioVDirSt word <-- 44 ioVBlLn word <-- 46 ioVNmAlBlks word <-- 48 ioVAlBlkSiz long word <-- 52 ioVClpSiz long word <-- 56 ioAlBlSt word <-- 58 ioVNxtFNum long word <-- 62 ioVFrBlk word PBGetVInfo returns information about the specified volume. If ioVolIndex is positive, the File Manager attempts to use it to find the volume; for instance, if ioVolIndex is 2, the File Manager will attempt to access the second mounted volume. If ioVolIndex is negative, the File Manager uses ioNamePtr and ioVRefNum in the standard way (described in the section “Specifying Volumes, Directories, and Files”) to determine which volume. If ioVolIndex is 0, the File Manager attempts to access the volume by using ioVRefNum only. The volume reference number is returned in ioVRefNum, and a pointer to the volume name is returned in ioNamePtr (unless ioNamePtr is NIL). If a working directory reference number is passed in ioVRefNum (or if the default directory is a subdirectory), the number of files and directories in the specified directory (the directory’s valence) will be returned in ioVNmFls. Also, the volume reference number won’t be returned; ioVRefNum will still contain the working directory reference number. Warning: IOVNmAlBlks and ioVFrBlks, which are actually unsigned integers, are clipped to 31744 ($7C00) regardless of the size of the volume. Result codes noErr No error nsvErr No such volume paramErr No default volume æKY PBGetVol æFc Files.h æT Function æD pascal OSErr PBGetVol(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetVol((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-104, IV-131 æC Trap macro _GetVol Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-- 18 ioNamePtr pointer <-- 22 ioVRefNum word PBGetVol returns a pointer to the name of the default volume in ioNamePtr (unless ioNamePtr is NIL) and its volume reference number in ioVRefNum. If a default directory was set with a previous PBSetVol call, a pointer to its name will be returned in ioNamePtr and its working directory reference number in ioVRefNum. Result codes noErr No error nsvErr No default volume æKY PBSetVol æFc Files.h æT Function æD pascal OSErr PBSetVol(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetVol((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-105, IV-132 æC Trap macro _SetVol Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word PBSetVol sets the default volume to the mounted volume specified by ioNamePtr or ioVRefNum. On hierarchical volumes, PBSetVol also sets the root directory as the default directory. Result codes noErr No error bdNamErr Bad volume name nsvErr No such volume paramErr No default volume æKY PBFlushVol æFc Files.h æT Function æD pascal OSErr PBFlushVol(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBFlushVol((ParmBlkPtr) paramBlock,(Boolean) async); æMM æRI II-105, IV-133 æC Trap macro _FlushVol Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word On the volume specified by ioNamePtr or ioVRefNum, PBFlushVol writes descriptive information about the volume, the contents of the associated volume buffer, and all access path buffers for the volume (if they’ve changed since the last time PBFlushVol was called). Note: The date and time of the last modification to the volume are set when the modification is made, not when the volume is flushed. Result codes noErr No error bdNamErr Bad volume name extFSErr External file system ioErr I/O error nsDrvErr No such drive nsvErr No such volume paramErr No default volume æKY PBCreate æFc Files.h æT Function æD pascal OSErr PBCreate(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBCreate((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-107, IV-145 æC Trap macro _Create Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 26 ioFVersNum byte PBCreate creates a new file (both forks) having the name pointed to by ioNamePtr (and on flat volumes, the version number ioVersNum) on the volume specified by ioVRefNum. The new file is unlocked and empty. The date and time of its creation and last modification are set to the current date and time. If the file created isn’t temporary (that is, if it will exist after the application terminates), the application should call PBSetFInfo (after PBCreate) to fill in the information needed by the Finder. Assembly-language note: If a desk accessory creates a file, it should always create it in the directory containing the system folder. The working directory reference number for this directory is stored in the global variable BootDrive; you can pass it in ioVRefNum. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version dirFulErr File directory full extFSErr External file system ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBDelete æFc Files.h æT Function æD pascal OSErr PBDelete(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDelete((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-119, IV-147 æC Trap macro _Delete Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 26 ioFVersNum byte PBDelete removes the closed file having the name pointed to by ioNamePtr (and on flat volumes, the version number ioVersNum) from the volume pointed to by ioVRefNum. PBHDelete can be used to delete an empty directory as well. Note: This function will delete both forks of the file. Result codes noErr No error bdNamErr Bad file name extFSErr External file system fBsyErr File busy, directory not empty, or working directory control block open fLckdErr File locked fnfErr File not found nsvErr No such volume ioErr I/O error vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBOpenRF æFc Files.h æT Function æD pascal OSErr PBOpenRF(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBOpenRF((ParmBlkPtr) paramBlock,(Boolean) async); æMM æRT 74 æRI II-109, IV-137 æC Trap macro _OpenRF Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word <-- 24 ioRefNum word --> 26 ioVersNum byte --> 27 ioPermssn byte --> 28 ioMisc pointer PBOpenRF is identical to PBOpen, except that it opens the file’s resource fork instead of its data fork. Note: Normally you should access a file’s resource fork through the routines of the Resource Manager rather than the File Manager. PBOpenRF doesn’t read the resource map into memory; it’s really only useful for block-level operations such as copying files. Result codes noErr No error bdNamErr Bad file name extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing permErr Attempt to open locked file for writing tmfoErr Too many files open æKY PBRename æFc Files.h æT Function æD pascal OSErr PBRename(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBRename((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-118, IV-153 æC Trap macro _Rename Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 26 ioVersNum byte --> 28 ioMisc pointer Given a pointer to a file name in ioNamePtr (and on flat volumes, a version number in ioVersNum), PBRename changes the name of the file to the name pointed to by ioMisc. (If the name pointed to by ioNamePtr contains one or more colons, so must the name pointed to by ioMisc.) Access paths currently in use aren’t affected. Given a pointer to a volume name in ioNamePtr or a volume reference number in ioVRefNum, it changes the name of the volume to the name pointed to by ioMisc. If a volume to be renamed is specified by its volume reference number, ioNamePtr can be NIL. Warning: If a volume to be renamed is specified by its volume name, be sure that it ends with a colon, or Rename will consider it a file name. Result codes noErr No error bdNamErr Bad file name dirFulErr File directory full dupFNErr Duplicate file name and version extFSErr External file system fLckdErr File locked fnfErr File not found fsRnErr Problem during rename ioErr I/O error nsvErr No such volume paramErr No default volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBGetFInfo æFc Files.h æT Function æD pascal OSErr PBGetFInfo(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetFInfo((ParmBlkPtr) paramBlock,(Boolean) async); æRT 24 æRI II-115, IV-148, N24-1, N68-1 æC Trap macro _GetFileInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-> 18 ioNamePtr pointer --> 22 ioVRefNum word <-- 24 ioFRefNum word --> 26 ioFVersNum byte --> 28 ioFDirIndex word <-- 30 ioFlAttrib byte <-- 31 ioFlVersNum byte <-- 32 ioFlFndrInfo 16 bytes <-- 48 ioFlNum long word <-- 52 ioFlStBlk word <-- 54 ioFlLgLen long word <-- 58 ioFlPyLen long word <-- 62 ioFlRStBlk word <-- 64 ioFlRLgLen long word <-- 68 ioFlRPyLen long word <-- 72 ioFlCrDat long word <-- 76 ioFlMdDat long word PBGetFInfo returns information about the specified file. If ioFDirIndex is positive, the File Manager returns information about the file whose directory index is ioFDirIndex on the volume specified by ioVRefNum. (See the section “Data Organization on Volumes” if you’re interested in using this method.) Note: If a working directory reference number is specified in ioVRefNum, the File Manager returns information about the file whose directory index is ioFDirIndex in the specified directory. If ioFDirIndex is negative or 0, the File Manager returns information about the file having the name pointed to by ioNamePtr (and on flat volumes, the version number ioFVersNum) on the volume specified by ioVRefNum. If the file is open, the reference number of the first access path found is returned in ioFRefNum, and the name of the file is returned in ioNamePtr (unless ioNamePtr is NIL). Result codes noErr No error bdNamErr Bad file name extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume æKY PBSetFInfo æFc Files.h æT Function æD pascal OSErr PBSetFInfo(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetFInfo((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-116, IV-150 æC Trap macro _SetFileInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 26 ioFVersNum byte --> 32 ioFlFndrInfo 16 bytes --> 72 ioFlCrDat long word --> 76 ioFlMdDat long word PBSetFInfo sets information (including the date and time of creation and modification, and information needed by the Finder) about the file having the name pointed to by ioNamePtr (and on flat volumes, the version number ioFVersNum) on the volume specified by ioVRefNum. You should call PBGetFInfo just before PBSetFInfo, so the current information is present in the parameter block. Result codes noErr No error bdNamErr Bad file name extFSErr External file system fLckdErr File locked fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBSetFLock æFc Files.h æT Function æD pascal OSErr PBSetFLock(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetFLock((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-116, IV-151 æC Trap macro _SetFilLock Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 26 ioFVersNum byte PBSetFLock locks the file having the name pointed to by ioNamePtr (and on flat volumes, the version number ioFVersNum) on the volume specified by ioVRefNum. Access paths currently in use aren’t affected. Result codes noErr No error extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBRstFLock æFc Files.h æT Function æD pascal OSErr PBRstFLock(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBRstFLock((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-117, IV-152 æC Trap macro _RstFilLock Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 26 ioFVersNum byte PBRstFLock unlocks the file having the name pointed to by ioNamePtr (and on flat volumes, the version number ioFVersNum) on the volume specified by ioVRefNum. Access paths currently in use aren’t affected. Result codes noErr No error extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBSetFVers æFc Files.h æT Function æD pascal OSErr PBSetFVers(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetFVers((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-117, IV-153 æC Trap macro _SetFilType Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 26 ioVersNum byte --> 28 ioMisc byte PBSetFVers has no effect on hierarchical volumes. On flat volumes, PBSetFVers changes the version number of the file having the name pointed to by ioNamePtr and version number ioVersNum, on the volume specified by ioVRefNum, to the version number stored in the high-order byte of ioMisc. Access paths currently in use aren’t affected. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version extFSErr External file system fLckdErr File locked fnfErr File not found nsvErr No such volume ioErr I/O error paramErr No default volume vLckdErr Software volume lock wPrErr Hardware volume lock wrgVolTypErr Attempt to perform hierarchical operation on a flat volume æKY PBAllocate æFc Files.h æT Function æD pascal OSErr PBAllocate(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBAllocate((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-113, IV-143 æC Trap macro _Allocate Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 36 ioReqCount long word <-- 40 ioActCount long word PBAllocate adds ioReqCount bytes to the open file whose access path is specified by ioRefNum, and sets the physical end-of-file to one byte beyond the last block allocated. The number of bytes actually allocated is rounded up to the nearest multiple of the allocation block size, and returned in ioActCount. If there isn’t enough empty space on the volume to satisfy the allocation request, PBAllocate allocates the rest of the space on the volume and returns dskFulErr as its function result. Note: Even if the total number of requested bytes is unavailable, PBAllocate will allocate whatever space, contiguous or not, is available. To force the allocation of the entire requested space as a contiguous piece, call PBAllocContig instead. Result codes noErr No error dskFulErr Disk full fLckdErr File locked fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing wrPermErr Read/write permission doesn’t allow writing æKY PBGetEOF æFc Files.h æT Function æD pascal OSErr PBGetEOF(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetEOF((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-112, IV-142 æC Trap macro _GetEOF Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word <-- 28 ioMisc long word PBGetEOF returns, in ioMisc, the logical end-of-file of the open file whose access path is specified by ioRefNum. Result codes noErr No error extFSErr External file system fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number æKY PBSetEOF æFc Files.h æT Function æD pascal OSErr PBSetEOF(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetEOF((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-112, IV-142 æC Trap macro _SetEOF Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 28 ioMisc long word PBSetEOF sets the logical end-of-file of the open file, whose access path is specified by ioRefNum, to ioMisc. If you attempt to set the logical end-of-file beyond the physical end-of-file, another allocation block is added to the file; if there isn’t enough space on the volume, no change is made, and PBSetEOF returns dskFulErr as its function result. If ioMisc is 0, all space occupied by the file on the volume is released. Result codes noErr No error dskFulErr Disk full extFSErr External file system fLckdErr File locked fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing æKY PBGetFPos æFc Files.h æT Function æD pascal OSErr PBGetFPos(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetFPos((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-111, IV-141 æC Trap macro _GetFPos Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word <-- 36 ioReqCount long word <-- 40 ioActCount long word <-- 44 ioPosMode word <-- 46 ioPosOffset long word PBGetFPos returns, in ioPosOffset, the mark of the open file whose access path is specified by ioRefNum. It sets ioReqCount, ioActCount, and ioPosMode to 0. Result codes noErr No error extFSErr External file system fnOpnErr File not open gfpErr Error during GetFPos ioErr I/O error rfNumErr Bad reference number æKY PBSetFPos æFc Files.h æT Function æD pascal OSErr PBSetFPos(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetFPos((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-111, IV-141 æC Trap macro _SetFPos Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 44 ioPosMode word <-> 46 ioPosOffset long word PBSetFPos sets the mark of the open file whose access path is specified by ioRefNum to the position specified by ioPosMode and ioPosOffset. The position at which the mark is actually set is returned in ioPosOffset. If you try to set the mark past the logical end-of-file, PBSetFPos moves the mark to the end-of-file and returns eofErr as its function result. Result codes noErr No error eofErr End-of-file extFSErr External file system fnOpnErr File not open ioErr I/O error posErr Attempt to position before start of file rfNumErr Bad reference number æKY PBFlushFile æFc Files.h æT Function æD pascal OSErr PBFlushFile(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBFlushFile((ParmBlkPtr) paramBlock,(Boolean) async); æRI II-114, IV-144 æC Trap macro _FlushFile Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word PBFlushFile writes the contents of the access path buffer indicated by ioRefNum to the volume, and updates the file’s entry in the file directory (or in the file catalog, in the case of hierarchical volumes). Warning: Some information stored on the volume won’t be correct until PBFlushVol is called. Result codes noErr No error extFSErr External file system fnfErr File not found fnOpnErr File not open ioErr I/O error nsvErr No such volume rfNumErr Bad reference number æKY PBMountVol æFc Files.h æT Function æD pascal OSErr PBMountVol(ParmBlkPtr paramBlock); æDT OSErr myVariable = PBMountVol((ParmBlkPtr) paramBlock); æMM æRT 134 æRI II-103, IV-128 æC »Accessing Volumes To get the volume reference number of a volume, given the path reference number of a file on that volume, both Pascal and assembly-language programmers can call the high-level File Manager function GetVRefNum. Assembly-language programmers may prefer calling the function GetFCBInfo (described below in the section “Data Structures in Memory”). FUNCTION PBMountVol (paramBlock: ParmBlkPtr) : OSErr; Trap macro _MountVol Parameter block <-- 16 ioResult word <-> 22 ioVRefNum word PBMountVol mounts the volume in the drive specified by ioVRefNum, and returns a volume reference number in ioVRefNum. If there are no volumes already mounted, this volume becomes the default volume. PBMountVol is always executed synchronously. Note: When mounting hierarchical volumes, PBMountVol opens two files needed for maintaining file directory and file mapping information. PBMountVol can fail if there are no access paths available for these two files; it will return tmfoErr as its function result. Result codes noErr No error badMDBErr Bad master directory block extFSErr External file system ioErr I/O error memFullErr Not enough room in heap zone noMacDskErr Not a Macintosh disk nsDrvErr No such drive paramErr Bad drive number tmfoErr Too many files open volOnLinErr Volume already on-line æKY PBUnmountVol æFc Files.h æT Function æD pascal OSErr PBUnmountVol(ParmBlkPtr paramBlock); æDT OSErr myVariable = PBUnmountVol((ParmBlkPtr) paramBlock); æRI II-106, IV-134 æC Trap macro _UnmountVol Parameter block <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word PBUnmountVol unmounts the volume specified by ioNamePtr or ioVRefNum, by calling PBFlushVol to flush the volume, closing all open files on the volume, and releasing the memory used for the volume. PBUnmountVol is always executed synchronously. Warning: Don’t unmount the startup volume. Note: Unmounting a volume does not close working directories; to release the memory allocated to a working directory, call PBCloseWD. Result codes noErr No error bdNamErr Bad volume name extFSErr External file system ioErr I/O error nsDrvErr No such drive nsvErr No such volume paramErr No default volume æKY PBEject æFc Files.h æT Function æD pascal OSErr PBEject(ParmBlkPtr paramBlock); æDT OSErr myVariable = PBEject((ParmBlkPtr) paramBlock); æMM æRI II-107, IV-135 æC Trap macro _Eject Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word PBEject flushes the volume specified by ioNamePtr or ioVRefNum, places it off-line, and then ejects the volume. Assembly-language note: You may invoke the macro _Eject asynchronously; the first part of the call is executed synchronously, and the actual ejection is executed asynchronously. Result codes noErr No error bdNamErr Bad volume name extFSErr External file system ioErr I/O error nsDrvErr No such drive nsvErr No such volume paramErr No default volume æKY PBOffLine æFc Files.h æT Function æD pascal OSErr PBOffLine(ParmBlkPtr paramBlock); æDT OSErr myVariable = PBOffLine((ParmBlkPtr) paramBlock); æMM æRI II-106, IV-134 æC Trap macro _OffLine Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word PBOffLine places off-line the volume specified by ioNamePtr or ioVRefNum, by calling PBFlushVol to flush the volume and releasing all the memory used for the volume except for the volume control block. PBOffLine is always executed synchronously. Result codes noErr No error bdNamErr Bad volume name extFSErr External file system ioErr I/O error nsDrvErr No such drive nsvErr No such volume paramErr No default volume æKY PBCatSearch æFc Files.h æT Function æD pascal OSErr PBCatSearch(CSParamPtr paramBlock,Boolean async); æDT OSErr myVariable = PBCatSearch((CSParamPtr) paramBlock,(Boolean) async); æMM æRI VI æC Parameter Block Æ 12 ioCompletion pointer pointer to completion routine ¨ 16 ioResult word result code Æ 18 ioNamePtr pointer pointer to volume name Æ 22 ioVRefNum word vRefNum or WDRefNum Æ 24 FSSpecArrayPtr pointer pointer to array of matches Æ 28 ioReqMatchCount long maximum match count wanted ¨ 32 ioActMatchCount long actual match count Æ 36 ioSpecBits long enable bits for fields in ioSpecs Æ 40 ioSpec1 CinfoPBPtr values and lower bounds Æ 44 ioSpec2 CinfoPBPtr masks and upper bounds Æ 48 ioSearchTime long maximum elapsed search time Æ 52 ioCatPosition CatPosition current catalog position Æ 56 ioRBuffer pointer pointer to optional read buffer Æ 60 ioRBufLen long length of optional read buffer PBCatSearch searches the volume you specify in the parameter block for files that match two coordinated sets of selection criteria. PBCatSearch returns the names and directory IDs for the files and directories that match the criteria in an array of IDs and names. Parameter Meaning ioCompletion A pointer to the completion routine. ioResult Result code. ioNamePtr Pointer to volume name. ioFSSpecArrayPtr A pointer to an array where the file and directory names that match the selection criteria are returned. ioReqMatchCount The approximate maximum number of matches to return in the ioReqMatchCount field. Use this field to avoid a possible glut of matches for criteria that prove to be too general. ioActMatchCount The number of actual matches found. ioSpecBits The fields of the parameter blocks ioSpec1 and ioSpec2 that are relevant to the search. See “Searching a Volume” for the values of ioSpecBits. ioSpec1 A pointer to a CInfoPBRec parameter block that contains values and the lower bounds of ranges for the fields selected by ioSpecBits. ioSpec2 A pointer to a second CInfoPBRec parameter block that contains masks and upper bounds of ranges for the fields selected by ioSpecBits. ioSearchTime A time limit on the time taken for a search. Use this field to limit the run time of a single call to PBCatSearch. ioCatPosition A position in the catalog where searching should begin. Use this field to keep an index into the catalog when breaking PBCatSearch down into a number of shorter searches. To start at the beginning of the catalog, set ioCatPosition to 0. Before exiting after an interrupted search, PBCatSearch sets it to the next record to be searched. To resume where the previous call stopped, pass the output of the previous call as input to the next. ioRBuffer A pointer to an optional read buffer. The ioRBuffer and ioRBufferLen fields let you specify a part of memory as a read buffer, increasing search speed. ioRBufLen The length of the buffer pointed to by ioRBuffer. Buffer effectiveness varies with models and configurations, but a 32 KB buffer is likely to be optimal. Even a 1 KB buffer provides some performance improvement. See the section “Using the File Manager” for a more complete description of PBCatSearch. Result codes noErr No error extFSErr External file system ioErr I/O error nsvErr No such volume catalogChangedErr The catalog has changed and CatPosition may be invalid paramErr Numerous causes æKY AddDrive æFc Files.h æT Function æD pascal void AddDrive(short drvrRefNum,short drvNum,DrvQElPtr qEl); æDT AddDrive((short) drvrRefNum,(short) drvNum,(DrvQElPtr) qEl); æRT 36, 108 æRI N36, N108-1 æC æKY FSOpen æFc Files.h æT Function æD pascal OSErr FSOpen(const Str255 fileName,short vRefNum,short *refNum); æDT OSErr myVariable = FSOpen((const Str255) fileName,(short) vRefNum,(short *) refNum); æRT 102 æRI II-91, IV-109, P-131, 171 æC [Not in ROM] FSOpen creates an access path to the file having the name fileName on the volume specified by vRefNum. A path reference number is returned in refNum. The access path’s read/write permission is set to whatever the file’s open permission allows. Note: There’s no guarantee that any bytes have been written until FlushVol is called. Result codes noErr No error bdNamErr Bad file name extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing tmfoErr Too many files open æKY fsopen æFc Files.h æT Function æD OSErr fsopen(char *fileName,short vRefNum,short *refNum); æDT OSErr myVariable = fsopen((char *) fileName,(short) vRefNum,(short *) refNum); æC æKY FSClose æFc Files.h æT Function æD pascal OSErr FSClose(short refNum); æDT OSErr myVariable = FSClose((short) refNum); æRT 102 æRI II-94, IV-112, P-132, 133, 171 æC [Not in ROM] FSClose removes the access path specified by refNum, writes the contents of the volume buffer to the volume, and updates the file’s entry in the file directory. Note: There’s no guarantee that any bytes have been written until FlushVol is called. Result codes noErr No error extFSErr External file system fnfErr File not found fnOpnErr File not open ioErr I/O error nsvErr No such volume rfNumErr Bad reference number æKY FSRead æFc Files.h æT Function æD pascal OSErr FSRead(short refNum,long *count,Ptr buffPtr); æDT OSErr myVariable = FSRead((short) refNum,(long *) count,(Ptr) buffPtr); æRI IV-109, P-131, 171 æC [Not in ROM] FSRead attempts to read the number of bytes specified by the count parameter from the open file whose access path is specified by refNum, and transfer them to the data buffer pointed to by buffPtr. The read operation begins at the current mark, so you might want to precede this with a call to SetFPos. If you try to read past the logical end-of-file, FSRead moves the mark to the end-of-file and returns eofErr as its function result. After the read is completed, the number of bytes actually read is returned in the count parameter. Result codes noErr No error eofErr End-of-file extFSErr External file system fnOpnErr File not open ioErr I/O error paramErr Negative count rfNumErr Bad reference number æKY FSWrite æFc Files.h æT Function æD pascal OSErr FSWrite(short refNum,long *count,Ptr buffPtr); æDT OSErr myVariable = FSWrite((short) refNum,(long *) count,(Ptr) buffPtr); æRI IV-110, P-132, 171 æC [Not in ROM] FSWrite takes the number of bytes specified by the count parameter from the buffer pointed to by buffPtr and attempts to write them to the open file whose access path is specified by refNum. The write operation begins at the current mark, so you might want to precede this with a call to SetFPos. After the write is completed, the number of bytes actually written is returned in the count parameter. Result codes noErr No error dskFulErr Disk full fLckdErr File locked fnOpnErr File not open ioErr I/O error paramErr Negative count rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing æKY GetVInfo æFc Files.h æT Function æD pascal OSErr GetVInfo(short drvNum,StringPtr volName,short *vRefNum,long *freeBytes); æDT OSErr myVariable = GetVInfo((short) drvNum,(StringPtr) volName,(short *) vRefNum,(long *) freeBytes); æRT 157 æRI II-89, IV-107, N157, low-level II-104, IV-129 æC »Accessing Volumes •••Refer to Technical Note #24:••• FUNCTION GetVInfo (drvNum: INTEGER; volName: StringPtr; VAR vRefNum: INTEGER; VAR freeBytes: LONGINT) : OSErr; [Not in ROM] •••Refer to Technical Note #157:••• GetVInfo returns the name, reference number, and available space (in bytes), in volName, vRefNum, and freeBytes, for the volume in the drive specified by drvNum. Result codes noErr No error nsvErr No default volume paramErr Bad drive number æKY getvinfo æFc Files.h æT Function æD OSErr getvinfo(short drvNum,char *volName,short *vRefNum,long *freeBytes); æDT OSErr myVariable = getvinfo((short) drvNum,(char *) volName,(short *) vRefNum,(long *) freeBytes); æC æKY GetFInfo æFc Files.h æT Function æD pascal OSErr GetFInfo(const Str255 fileName,short vRefNum,FInfo *fndrInfo); æDT OSErr myVariable = GetFInfo((const Str255) fileName,(short) vRefNum,(FInfo *) fndrInfo); æRI II-95, IV-113 æC [Not in ROM] For the file having the name fileName on the specified volume, GetFInfo returns information used by the Finder in fndrInfo (see the section “Information Used by the Finder”). Result codes noErr No error bdNamErr Bad file name extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume æKY getfinfo æFc Files.h æT Function æD OSErr getfinfo(char *fileName,short vRefNum,FInfo *fndrInfo); æDT OSErr myVariable = getfinfo((char *) fileName,(short) vRefNum,(FInfo *) fndrInfo); æC æKY GetVol æFc Files.h æT Function æD pascal OSErr GetVol(StringPtr volName,short *vRefNum); æDT OSErr myVariable = GetVol((StringPtr) volName,(short *) vRefNum); æRT 77,140 æRI N77-2, N140 high-level II-89, IV-107 low-level II-104, IV-131 æC [Not in ROM] GetVol returns the name of the default volume in volName and its volume reference number in vRefNum. Result codes noErr No error nsvErr No such volume æKY getvol æFc Files.h æT Function æD OSErr getvol(char *volName,short *vRefNum); æDT OSErr myVariable = getvol((char *) volName,(short *) vRefNum); æC æKY SetVol æFc Files.h æT Function æD pascal OSErr SetVol(StringPtr volName,short vRefNum); æDT OSErr myVariable = SetVol((StringPtr) volName,(short) vRefNum); æRI II-89, IV-107 low-level II-105, IV-132 æC [Not in ROM] SetVol sets the default volume to the mounted volume specified by volName or vRefNum. Result codes noErr No error bdNamErr Bad volume name nsvErr No such volume paramErr No default volume æKY setvol æFc Files.h æT Function æD OSErr setvol(char *volName,short vRefNum); æDT OSErr myVariable = setvol((char *) volName,(short) vRefNum); æC æKY UnmountVol æFc Files.h æT Function æD pascal OSErr UnmountVol(StringPtr volName,short vRefNum); æDT OSErr myVariable = UnmountVol((StringPtr) volName,(short) vRefNum); æRT 180 æRI II-90, IV-108 low-level II-106, IV-134 æC [Not in ROM] UnmountVol unmounts the volume specified by volName or vRefNum, by calling FlushVol to flush the volume buffer, closing all open files on the volume, and releasing the memory used for the volume. Warning: Don’t unmount the startup volume. Result codes noErr No error bdNamErr Bad volume name extFSErr External file system ioErr I/O error nsDrvErr No such drive nsvErr No such volume paramErr No default volume æKY unmountvol æFc Files.h æT Function æD OSErr unmountvol(char *volName,short vRefNum); æDT OSErr myVariable = unmountvol((char *) volName,(short) vRefNum); æC æKY Eject æFc Files.h æT Function æD pascal OSErr Eject(StringPtr volName,short vRefNum); æDT OSErr myVariable = Eject((StringPtr) volName,(short) vRefNum); æMM æRI II-90, IV-108 low-level II-107, IV-135 æC [Not in ROM] Eject flushes the volume specified by volName or vRefNum, places it off-line, and then ejects the volume. Result codes noErr No error bdNamErr Bad volume name extFSErr External file system ioErr I/O error nsDrvErr No such drive nsvErr No such volume paramErr No default volume æKY eject æFc Files.h æT Function æD OSErr eject(char *volName,short vRefNum); æDT OSErr myVariable = eject((char *) volName,(short) vRefNum); æC æKY FlushVol æFc Files.h æT Function æD pascal OSErr FlushVol(StringPtr volName,short vRefNum); æDT OSErr myVariable = FlushVol((StringPtr) volName,(short) vRefNum); æMM æRI P-132, 133 high-level II-89, IV-108 low-level II-105, IV-133 æC [Not in ROM] On the volume specified by volName or vRefNum, FlushVol writes the contents of the associated volume buffer and descriptive information about the volume (if they’ve changed since the last time FlushVol was called). Result codes noErr No error bdNamErr Bad volume name extFSErr External file system ioErr I/O error nsDrvErr No such drive nsvErr No such volume paramErr No default volume æKY flushvol æFc Files.h æT Function æD OSErr flushvol(char *volName,short vRefNum); æDT OSErr myVariable = flushvol((char *) volName,(short) vRefNum); æC æKY Create æFc Files.h æT Function æD pascal OSErr Create(const Str255 fileName,short vRefNum,OSType creator, OSType fileType); æDT OSErr myVariable = Create((const Str255) fileName,(short) vRefNum,(OSType) creator,() OSType fileType); æRI II-90, IV-112 low-level II-107, IV-145 æC [Not in ROM] Create creates a new file (both forks) with the specified name, file type, and creator on the specified volume. (File type and creator are discussed in the Finder Interface chapter.) The new file is unlocked and empty. The date and time of its creation and last modification are set to the current date and time. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version dirFulErr File directory full extFSErr External file system ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY create æFc Files.h æT Function æD OSErr create(char *fileName,short vRefNum,OSType creator,OSType fileType); æDT OSErr myVariable = create((char *) fileName,(short) vRefNum,(OSType) creator,(OSType) fileType); æRI II-90, IV-112 low-level II-107, IV-145 æC Create creates a new file (both forks) with the specified name, file type, and creator on the specified volume. (File type and creator are discussed in the Finder Interface chapter.) The new file is unlocked and empty. The date and time of its creation and last modification are set to the current date and time. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version dirFulErr File directory full extFSErr External file system ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY FSDelete æFc Files.h æT Function æD pascal OSErr FSDelete(const Str255 fileName,short vRefNum); æDT OSErr myVariable = FSDelete((const Str255) fileName,(short) vRefNum); æRI II-97, IV-113 æC [Not in ROM] FSDelete removes the closed file having the name fileName from the specified volume. Note: This function will delete both forks of a file. Result codes noErr No error bdNamErr Bad file name extFSErr External file system fBsyErr File busy fLckdErr File locked fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY fsdelete æFc Files.h æT Function æD OSErr fsdelete(char *fileName,short vRefNum); æDT OSErr myVariable = fsdelete((char *) fileName,(short) vRefNum); æC æKY OpenRF æFc Files.h æT Function æD pascal OSErr OpenRF(const Str255 fileName,short vRefNum,short *refNum); æDT OSErr myVariable = OpenRF((const Str255) fileName,(short) vRefNum,(short *) refNum); æRT 74 æRI II-91, IV-109 low-level II-109, IV-137 æC [Not in ROM] OpenRF is similar to FSOpen; the only difference is that OpenRF opens the resource fork of the specified file rather than the data fork. A path reference number is returned in refNum. The access path’s read/write permission is set to whatever the file’s open permission allows. Note: Normally you should access a file’s resource fork through the routines of the Resource Manager rather than the File Manager. OpenRF doesn’t read the resource map into memory; it’s really only useful for block-level operations such as copying files. Result codes noErr No error bdNamErr Bad file name extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing tmfoErr Too many files open æKY openrf æFc Files.h æT Function æD OSErr openrf(char *fileName,short vRefNum,short *refNum); æDT OSErr myVariable = openrf((char *) fileName,(short) vRefNum,(short *) refNum); æC æKY Rename æFc Files.h æT Function æD pascal OSErr Rename(const Str255 oldName,short vRefNum,const Str255 newName); æDT OSErr myVariable = Rename((const Str255) oldName,(short) vRefNum,(const Str255) newName); æRI II-96, IV-114 low-level II-118, IV-153 æC [Not in ROM] Given a file name in oldName, Rename changes the name of the file to newName. Access paths currently in use aren’t affected. Given a volume name in oldName or a volume reference number in vRefNum, Rename changes the name of the specified volume to newName. Warning: If you’re renaming a volume, be sure that both names end with a colon. Result codes noErr No error bdNamErr Bad file name dirFulErr Directory full dupFNErr Duplicate file name extFSErr External file system fLckdErr File locked fnfErr File not found fsRnErr Problem during rename ioErr I/O error nsvErr No such volume paramErr No default volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY fsrename æFc Files.h æT Function æD OSErr fsrename(char *oldName,short vRefNum,char *newName); æDT OSErr myVariable = fsrename((char *) oldName,(short) vRefNum,(char *) newName); æRI II-96, IV-114 low-level II-118, IV-153 æC fsrename is actually the "c" version of the Macintosh ROM call, Rename, which uses c strings. It was not named "rename" to avoid conflict with the ANSI call by that name. æKY SetFInfo æFc Files.h æT Function æD pascal OSErr SetFInfo(const Str255 fileName,short vRefNum,const FInfo *fndrInfo); æDT OSErr myVariable = SetFInfo((const Str255) fileName,(short) vRefNum,(const FInfo *) fndrInfo); æRI II-95, IV-114 æC [Not in ROM] For the file having the name fileName on the specified volume, SetFInfo sets information used by the Finder to fndrInfo (see the section “Information Used by the Finder”). Result codes noErr No error extFSErr External file system fLckdErr File locked fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY setfinfo æFc Files.h æT Function æD OSErr setfinfo(char *fileName,short vRefNum,FInfo *fndrInfo); æDT OSErr myVariable = setfinfo((char *) fileName,(short) vRefNum,(FInfo *) fndrInfo); æC æKY SetFLock æFc Files.h æT Function æD pascal OSErr SetFLock(const Str255 fileName,short vRefNum); æDT OSErr myVariable = SetFLock((const Str255) fileName,(short) vRefNum); æRI II-95, IV-114 æC [Not in ROM] SetFLock locks the file having the name fileName on the specified volume. Access paths currently in use aren’t affected. Result codes noErr No error extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY setflock æFc Files.h æT Function æD OSErr setflock(char *fileName,short vRefNum); æDT OSErr myVariable = setflock((char *) fileName,(short) vRefNum); æC æKY RstFLock æFc Files.h æT Function æD pascal OSErr RstFLock(const Str255 fileName,short vRefNum); æDT OSErr myVariable = RstFLock((const Str255) fileName,(short) vRefNum); æRI II-96, IV-114 æC [Not in ROM] RstFLock unlocks the file having the name fileName on the specified volume. Access paths currently in use aren’t affected. Result codes noErr No error extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY rstflock æFc Files.h æT Function æD OSErr rstflock(char *fileName,short vRefNum); æDT OSErr myVariable = rstflock((char *) fileName,(short) vRefNum); æC æKY Allocate æFc Files.h æT Function æD pascal OSErr Allocate(short refNum,long *count); æDT OSErr myVariable = Allocate((short) refNum,(long *) count); æRI IV-143 æC [Not in ROM] Allocate adds the number of bytes specified by the count parameter to the open file whose access path is specified by refNum, and sets the physical end-of-file to one byte beyond the last block allocated. The number of bytes actually allocated is rounded up to the nearest multiple of the allocation block size, and returned in the count parameter. If there isn’t enough empty space on the volume to satisfy the allocation request, Allocate allocates the rest of the space on the volume and returns dskFulErr as its function result. Result codes noErr No error dskFulErr Disk full fLckdErr File locked fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing æKY GetEOF æFc Files.h æT Function æD pascal OSErr GetEOF(short refNum,long *logEOF); æDT OSErr myVariable = GetEOF((short) refNum,(long *) logEOF); æRI P-132, 172 high-level II-93, IV-111 low-level II-112, IV-142 æC [Not in ROM] GetEOF returns, in logEOF, the logical end-of-file of the open file whose access path is specified by refNum. Result codes noErr No error extFSErr External file system fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number æKY SetEOF æFc Files.h æT Function æD pascal OSErr SetEOF(short refNum,long logEOF); æDT OSErr myVariable = SetEOF((short) refNum,(long) logEOF); æRI P-132, 180 high-level II-93, IV-111 low-level II-112, IV-142 æC [Not in ROM] SetEOF sets the logical end-of-file of the open file whose access path is specified by refNum to the position specified by logEOF. If you attempt to set the logical end-of-file beyond the physical end-of-file, the physical end-of-file is set to one byte beyond the end of the next free allocation block; if there isn’t enough space on the volume, no change is made, and SetEOF returns dskFulErr as its function result. If logEOF is 0, all space occupied by the file on the volume is released. Result codes noErr No error dskFulErr Disk full extFSErr External file system fLckdErr File locked fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing æKY GetFPos æFc Files.h æT Function æD pascal OSErr GetFPos(short refNum,long *filePos); æDT OSErr myVariable = GetFPos((short) refNum,(long *) filePos); æRI II-92, IV-110 low-level II-111, IV-141 æC [Not in ROM] GetFPos returns, in filePos, the mark of the open file whose access path is specified by refNum. Result codes noErr No error extFSErr External file system fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number æKY SetFPos æFc Files.h æT Function æD pascal OSErr SetFPos(short refNum,short posMode,long posOff); æDT OSErr myVariable = SetFPos((short) refNum,(short) posMode,(long) posOff); æRI P-131, 132, 180 high-level II-93, IV-110 low-level II-111, IV-141 æC [Not in ROM] SetFPos sets the mark of the open file whose access path is specified by refNum to the position specified by posMode and posOff (except when posMode is equal to fsAtMark, in which case posOff is ignored). PosMode indicates how to position the mark; it must contain one of the following values: CONST fsAtMark = 0; {at current mark} fsFromStart = 1; {set mark relative to beginning of file} fsFromLEOF = 2; {set mark relative to logical end-of-file} fsFromMark = 3; {set mark relative to current mark} If you specify fsAtMark, posOffset is ignored and the mark is left wherever it’s currently positioned. If you choose to set the mark (relative to either the beginning of the file, the logical end-of-file, or the current mark), posOffset specifies the byte offset from the chosen point (either positive or negative) where the mark should be set. If you try to set the mark past the logical end-of-file, SetFPos moves the mark to the end-of-file and returns eofErr as its function result. Result codes noErr No error eofErr End-of-file extFSErr External file system fnOpnErr File not open ioErr I/O error posErr Attempt to position before start of file rfNumErr Bad reference number æKY GetVRefNum æFc Files.h æT Function æD pascal OSErr GetVRefNum(short fileRefNum,short *vRefNum); æDT OSErr myVariable = GetVRefNum((short) fileRefNum,(short *) vRefNum); æRI II-89, IV-107 æC [Not in ROM] Given a path reference number in pathRefNum, GetVRefNum returns the volume reference number in vRefNum. Result codes noErr No error rfNumErr Bad reference number æKY PBOpenDF æFc Files.h æT Function æD pascal OSErr PBOpenDF(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBOpenDF((ParmBlkPtr) paramBlock,(Boolean) async); æRI VI æC OpenDF creates an access path to the data fork of a file. It is almost identical to PBFSOpen, which is documented in the File Manager chapter of Volume IV. The difference is that PBFSOpen can open both files and devices, but PBOpenDF can open only files. Using OpenDF instead of FSOpen when your application is opening a file prevents naming conflicts or ambiguities. æKY PBOpenWD æFc Files.h æT Function æD pascal OSErr PBOpenWD(WDPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBOpenWD((WDPBPtr) paramBlock,(Boolean) async); æRT 77, 190 æRI IV-158, N77-1 æC Trap macro _OpenWD Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer <-> 22 ioVRefNum word --> 28 ioWDProcID long word --> 48 ioWDDirID long word PBOpenWD takes the directory specified by ioVRefNum, ioWDDirID, and ioWDProcID and makes it a working directory. (You can also specify the directory using a combination of partial pathname and directory ID.) It returns a working directory reference number in ioVRefNum that can be used in subsequent calls. If a given directory has already been made a working directory using the same ioWDProcID, no new working directory will be opened; instead, the existing working directory reference number will be returned. If a given directory was already made a working directory using a different ioWDProcID, a new working directory reference number is returned. Result codes noErr No error tmwdoErr Too many working directories open æKY PBCloseWD æFc Files.h æT Function æD pascal OSErr PBCloseWD(WDPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBCloseWD((WDPBPtr) paramBlock,(Boolean) async); æRI IV-158 æC Trap macro _CloseWD Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 22 ioVRefNum word PBCloseWD releases the working directory whose working directory reference number is specified in ioVRefNum. Note: If a volume reference number is specified in ioVRefNum, PBCloseWD does nothing. Result codes noErr No error nsvErr No such volume æKY PBHSetVol æFc Files.h æT Function æD pascal OSErr PBHSetVol(WDPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHSetVol((WDPBPtr) paramBlock,(Boolean) async); æRT 140 æRI IV-133, N140 æC •••Refer to Technical Note #140:••• Trap macro _HSetVol Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 48 ioWDDirID long word PBHSetVol sets both the default volume and the default directory. The default directory to be used can be specified by either a volume reference number or a working directory reference number in ioVRefNum, a directory ID in ioWDDirID, or a pointer to a pathname (possibly NIL) in ioNamePtr. Note: Both the default volume and the default directory are used in calls made with no volume name and a volume reference number of zero. Result codes noErr No error nsvErr No default volume æKY PBHGetVol æFc Files.h æT Function æD pascal OSErr PBHGetVol(WDPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHGetVol((WDPBPtr) paramBlock,(Boolean) async); æRI IV-132 æC Trap macro _HGetVol Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-- 18 ioNamePtr pointer <-- 22 ioVRefNum word <-- 28 ioWDProcID long word <-- 32 ioWDVRefNum word <-- 48 ioWDDirID long word PBHGetVol returns the default volume and directory last set by either a PBSetVol or a PBHSetVol call. The reference number of the default volume is returned in ioVRefNum. Warning: IOVRefNum will return a working directory reference number (instead of the volume reference number) if, in the last call to PBSetVol or PBHSetVol, a working directory reference number was passed in this field. The volume reference number of the volume on which the default directory exists is returned in ioWDVRefNum. The directory ID of the default directory is returned in ioWDDirID. Result codes noErr No error nsvErr No default volume æKY PBCatMove æFc Files.h æT Function æD pascal OSErr PBCatMove(CMovePBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBCatMove((CMovePBPtr) paramBlock,(Boolean) async); æRI IV-157, VI æC Some existing HFS functions now support file IDs as appropriate, but their interface remains stable. This section describes how they accommodate file IDs. FUNCTION PBCatMove (paramBlock: HParamBlkPtr, async: Boolean) : OSErr; If a file ID exists for the file being moved, the file ID remains with the file. •••Refer to Technical Note #226:••• Trap macro _CatMove Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 28 ioNewName pointer --> 36 ioNewDirID long word --> 48 ioDirID long word PBCatMove moves files or directories from one directory to another. The name of the file or directory to be moved is pointed to by ioNamePtr; ioVRefNum contains either the volume reference number or working directory reference number. A directory ID can be specified in ioDirID. The name and directory ID of the directory to which the file or directory is to be moved are specified by ioNewName and ioNewDirID. PBCatMove is strictly a file catalog operation; it does not actually change the location of the file or directory on the disk. PBCatMove cannot move a file or directory to another volume (that is, ioVRefNum is used in specifying both the source and the destination). It also cannot be used to rename files or directories; for that, use PBHRename. Result codes noErr No error badMovErr Attempt to move into offspring bdNamErr Bad file name or attempt to move into a file dupFNErr Duplicate file name and version fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBDirCreate æFc Files.h æT Function æD pascal OSErr PBDirCreate(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDirCreate((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-146 æC Trap macro _DirCreate Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-> 18 ioNamePtr pointer --> 22 ioVRefNum word <-> 48 ioDirID long word PBDirCreate is identical to PBHCreate except that it creates a new directory instead of a file. You can specify the parent of the directory to be created in ioDirID; if it’s 0, the new directory will be placed in the root directory. The directory ID of the new directory is returned in ioDirID. Warning: PBDirCreate operates only with the hierarchical version of the File Manager; if used on a Macintosh equipped only with the 64K ROM version of the File Manager, it will generate a system error. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version dirFulErr File directory full dirNFErr Directory not found or incomplete pathname extFSErr External file system ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBGetWDInfo æFc Files.h æT Function æD pascal OSErr PBGetWDInfo(WDPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetWDInfo((WDPBPtr) paramBlock,(Boolean) async); æRT 77, 190 æRI IV-159, N77-5 æC Trap macro _GetWDInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-- 18 ioNamePtr pointer <-> 22 ioVRefNum word --> 26 ioWDIndex word <-> 28 ioWDProcID long word <-> 32 ioWDVRefNum word <-- 48 ioWDDirID long word PBGetWDInfo returns information about the specified working directory. The working directory can be specified either by its working directory reference number in ioVRefNum (in which case ioWDIndex should be 0), or by its index number in ioWDIndex. In the latter case, if ioVRefNum is nonzero, it’s interpreted as a volume specification (volume reference number or drive number), and only working directories on that volume are indexed. IOWDVRefNum always returns the volume reference number. IOVRefNum returns a working directory reference number when a working directory reference number is passed in that field; otherwise, it returns a volume reference number. The volume name is returned in ioNamePtr. If IOWDProcID is nonzero, only working directories with that identifier are indexed; otherwise all working directories are indexed. Result codes noErr No error nsvErr No such volume æKY PBGetFCBInfo æFc Files.h æT Function æD pascal OSErr PBGetFCBInfo(FCBPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetFCBInfo((FCBPBPtr) paramBlock,(Boolean) async); æRT 87 æRI IV-179, N87-1 æC Trap macro _GetFCBInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-- 18 ioNamePtr pointer <-> 22 ioVRefNum word <-> 24 ioRefNum word --> 28 ioFCBIndx long word <-- 32 ioFCBFlNm long word <-- 36 ioFCBFlags word <-- 38 ioFCBStBlk word <-- 40 ioFCBEOF long word <-- 44 ioFCBPLen long word <-- 48 ioFCBCrPs long word <-- 52 ioFCBVRefNum word <-- 54 ioFCBClpSiz long word <-- 58 ioFCBParID long word PBGetFCBInfo returns information about the specified open file. If ioFCBIndx is positive, the File Manager returns information about the file whose file number is ioFCBIndx on the volume specified by ioVRefNum (which may contain a drive number, volume reference number, or working directory reference number). If ioVRefNum is 0, all open files are indexed; otherwise, only open files on the specified volume are indexed. If ioFCBIndx is 0, the File Manager returns information about the file whose access path is specified by ioRefNum. Assembly-language note: The global variable FCBSPtr points to the length word of the file-control-block buffer. Each file control block contains 94 bytes of information about an access path; Figure 28 shows its structure (using the assembly-language offsets). •••Refer to Figure 28.••• Figure 28–A File Control Block 64K ROM note: The structure of a file control block in the 64K ROM version of the File Manager is a subset of the above structure. The old file control block contained only the fields up to and including fcbFlPos. FCBMdRByt (which corresponds to ioFCBFlags in the parameter block for PBGetFCBInfo) contains flags that describe the status of the file, as follows: Bit Meaning 0 Set if data can be written to the file 1 Set if the entry describes a resource fork 7 Set if the file has been changed since it was last flushed Warning: The size and structure of a file control block may be different in future versions of Macintosh system software. æKY PBGetCatInfo æFc Files.h æT Function æD pascal OSErr PBGetCatInfo(CInfoPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetCatInfo((CInfoPBPtr) paramBlock,(Boolean) async); æRT 68,69 æRI IV-155, V-391, N68-1, N69, VI æC Some existing HFS functions now support file IDs as appropriate, but their interface remains stable. This section describes how they accommodate file IDs. FUNCTION PBGetCatInfo (paramBlock: HParamBlkPtr, async: Boolean) : OSErr; You can use PBGetCatInfo to determine whether a file has a file ID. The value of the file ID is returned in ioDirID. Because that parameter could also represent a directory ID, call PBResolveFileID to see if the value is a real file ID. If you want to both determine whether a file ID exists for a file and create one if it doesn’t, use PBCreateFileID, which will either create a file ID or return fidExists. •••Refer to Technical Note #69:••• Trap macro _GetCatInfo Parameter block Files: Directories: --> 12 ioCompletion pointer --> 12 ioCompletion pointer <-- 16 ioResult word <-- 16 ioResult word <-> 18 ioNamePtr pointer <-> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 22 ioVRefNum word <-- 24 ioFRefNum word <-- 24 ioFRefNum word --> 28 ioFDirIndex word --> 28 ioFDirIndex word <-- 30 ioFlAttrib byte <-- 30 ioFlAttrib byte <-- 31 ioACUser byte access rights for directory only <-- 32 ioFlFndrInfo 16 bytes <-- 32 ioDrUsrWds 16 bytes <-> 48 ioDirID long word <-> 48 ioDrDirID long word <-- 52 ioFlStBlk word <-- 52 ioDrNmFls word <-- 54 ioFlLgLen long word <-- 58 ioFlPyLen long word <-- 62 ioFlRStBlk word <-- 64 ioFlRLgLen long word <-- 68 ioFlRPyLen long word <-- 72 ioFlCrDat long word <-- 72 ioDrCrDat long word <-- 76 ioFlMdDat long word <-- 76 ioDrMdDat long word <-- 80 ioFlBkDat long word <-- 80 ioDrBkDat long word <-- 84 ioFlXFndrInfo 16 bytes <-- 84 ioDrFndrInfo 16 bytes <-- 100 ioFlParID long word <-- 100 ioDrParID long word <-- 104 ioFlClpSiz long word PBGetCatInfo gets information about the files and directories in a file catalog. To determine whether the information is for a file or a directory, test bit 4 of ioFlAttrib, as described in the section “CInfoPBRec”. The information that’s returned for files is shown in the left column, and the corresponding information for directories is shown in the right column. If ioFDirIndex is positive, the File Manager returns information about the file or directory whose directory index is ioFDirIndex in the directory specified by ioVRefNum (this will be the root directory if a volume reference number is provided). If ioFDirIndex is 0, the File Manager returns information about the file or directory specified by ioNamePtr, in the directory specified by ioVRefNum (again, this will be the root directory if a volume reference number is provided). If ioFDirIndex is negative, the File Manager ignores ioNamePtr and returns information about the directory specified by ioDirID. With files, PBGetCatInfo is similar to PBHGetFileInfo but returns some additional information. If the file is open, the reference number of the first access path found is returned in ioFRefNum, and the name of the file is returned in ioNamePtr (unless ioNamePtr is NIL). For server volume directories, in addition to the normal return parameters the ioACUser field returns the user’s access rights in the following format: Bit 7 if set, user is not the owner of the directory. if clear, user is the owner of the directory. 6–3 Reserved; this is returned set to zero. 2 If set, user does not have Make Changes privileges to the directory. If clear, user has Make Changes privileges to the directory. 1 If set, user does not have See Files privileges to the directory. If clear, user has See Files privileges to the directory. 0 If set, user does not have See Folders privileges to the directory. If clear, user has See Folders privileges to the directory. For example, if ioACUser returns zero for a given server volume directory, you know that the user is the owner of the directory and has complete privileges to it. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume æKY PBSetCatInfo æFc Files.h æT Function æD pascal OSErr PBSetCatInfo(CInfoPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetCatInfo((CInfoPBPtr) paramBlock,(Boolean) async); æRI IV-156 æC Trap macro _SetCatInfo Parameter block Files: Directories: --> 12 ioCompletion pointer --> 12 ioCompletion pointer <-- 16 ioResult word <-- 16 ioResult word <-> 18 ioNamePtr pointer <-> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 22 ioVRefNum word --> 30 ioFlAttrib byte --> 30 ioFlAttrib byte --> 32 ioFlFndrInfo 16 bytes --> 32 ioDrUsrWds 16 bytes --> 48 ioDirID long word --> 48 ioDrDirID long word --> 72 ioFlCrDat long word --> 72 ioDrCrDat long word --> 76 ioFlMdDat long word --> 76 ioDrMdDat long word --> 80 ioFlBkDat long word --> 80 ioDrBkDat long word --> 84 ioFlXFndrInfo 16 bytes --> 84 ioDrFndrInfo 16 bytes --> 104 ioFlClpSiz long word PBSetCatInfo sets information about the files and directories in a catalog. With files, it’s similar to PBHSetFileInfo but lets you set some additional information. The information that can be set for files is shown in the left column, and the corresponding information for directories is shown in the right column. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume æKY PBAllocContig æFc Files.h æT Function æD pascal OSErr PBAllocContig(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBAllocContig((ParmBlkPtr) paramBlock,(Boolean) async); æRI IV-143 æC Trap macro _AllocContig Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 36 ioReqCount long word <-- 40 ioActCount long word PBAllocContig is identical to PBAllocate except that if there isn’t enough contiguous empty space on the volume to satisfy the allocation request, PBAllocContig will do nothing and will return dskFulErr as its function result. If you want to allocate whatever space is available, even when the entire request cannot be filled as a contiguous piece, call PBAllocate instead. Result codes noErr No error dskFulErr Disk full fLckdErr File locked fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing æKY PBLockRange æFc Files.h æT Function æD pascal OSErr PBLockRange(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBLockRange((ParmBlkPtr) paramBlock,(Boolean) async); æRT 186 æRI IV-138 æC •••Refer to Technical Note #186:••• Trap macro _LockRng Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 36 ioReqCount long word --> 44 ioPosMode word --> 46 ioPosOffset long word On a file opened with a shared read/write permission, PBLockRange is used in conjunction with PBRead and PBWrite to lock a certain portion of the file. PBLockRange uses the same parameters as both PBRead and PBWrite; by calling it immediately before PBRead, you can use the information present in the parameter block for the PBRead call. When you’re finished with the data (typically after a call to PBWrite), be sure to call PBUnlockRange to free up that portion of the file for subsequent PBRead calls. Warning: PBLockRange operates only with the hierarchical version of the File Manager; if used on a Macintosh equipped only with the 64K ROM version of the File Manager, it will generate a system error. Result codes noErr No error eofErr End-of-file extFSErr External file system fnOpnErr File not open ioErr I/O error paramErr Negative ioReqCount rfNumErr Bad reference number æKY PBUnlockRange æFc Files.h æT Function æD pascal OSErr PBUnlockRange(ParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBUnlockRange((ParmBlkPtr) paramBlock,(Boolean) async); æRT 186 æRI IV-139 æC Trap macro _UnlockRng Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 24 ioRefNum word --> 36 ioReqCount long word --> 44 ioPosMode word --> 46 ioPosOffset long word PBUnlockRange is used in conjunction with PBRead and PBWrite to unlock a certain portion of a file that you locked with PBLockRange. Warning: PBUnlockRange operates only with the hierarchical version of the File Manager; if used on a Macintosh equipped only with the 64K ROM version of the File Manager, it will generate a system error. Result codes noErr No error eofErr End-of-file extFSErr External file system fnOpnErr File not open ioErr I/O error paramErr Negative ioReqCount rfNumErr Bad reference number æKY PBSetVInfo æFc Files.h æT Function æD pascal OSErr PBSetVInfo(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetVInfo((HParmBlkPtr) paramBlock,(Boolean) async); æRT 204 æRI IV-131 æC •••Refer to Technical Note #204:••• Trap macro _SetVolInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 30 ioVCrDate long word --> 34 ioVLsMod long word --> 38 ioVAtrb word --> 52 ioVClpSiz long word --> 72 ioVBkUp long word --> 76 ioVSeqNum word --> 90 ioVFndrInfo 32 bytes PBSetVInfo lets you modify information about volumes. A pointer to a new name for the volume can be specified in ioNamePtr. The date and time of the volume’s creation and modification can be set with ioVCrDate and ioVLsMod respectively. Only bit 15 of ioVAtrb can be changed; setting it locks the volume. Note: The volume cannot be specified by name; you must use either the volume reference number or the drive number. Warning: PBSetVInfo operates only with the hierarchical version of the File Manager; if used on a Macintosh equipped only with the 64K ROM version of the File Manager, it will generate a system error. Result codes noErr No error nsvErr No such volume paramErr No default volume æKY PBHGetVInfo æFc Files.h æT Function æD pascal OSErr PBHGetVInfo(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHGetVInfo((HParmBlkPtr) paramBlock,(Boolean) async); æRT 24, 66, 67, 77, 106, 157 æRI IV-130, N66-1, N67-1, N77-5 æC Trap macro _HGetVInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-> 18 ioNamePtr pointer <-> 22 ioVRefNum word --> 28 ioVolIndex word <-- 30 ioVCrDate long word <-- 34 ioVLsMod long word <-- 38 ioVAtrb word <-- 40 ioVNmFls word <-- 42 ioVBitMap word <-- 44 ioVAllocPtr word <-- 46 ioVNmAlBlks word <-- 48 ioVAlBlkSiz long word <-- 52 ioVClpSiz long word <-- 56 ioAlBlSt word <-- 58 ioVNxtFNum long word <-- 62 ioVFrBlk word <-- 64 ioVSigWord word <-- 66 ioVDrvInfo word <-- 68 ioVDRefNum word <-- 70 ioVFSID word <-- 72 ioVBkUp long word <-- 76 ioVSeqNum word <-- 78 ioVWrCnt long word <-- 82 ioVFilCnt long word <-- 86 ioVDirCnt long word <-- 90 ioVFndrInfo 32 bytes PBHGetVInfo is similar in function to PBGetVInfo but returns a larger parameter block. In addition, PBHGetVInfo always returns the volume reference number in ioVRefNum (regardless of what was passed in). Also, ioVNmAlBlks and ioVFrBlks are not clipped as they are by PBGetVInfo. Result codes noErr No error nsvErr No such volume paramErr No default volume æKY PBHOpen æFc Files.h æT Function æD pascal OSErr PBHOpen(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHOpen((HParmBlkPtr) paramBlock,(Boolean) async); æRT 204 æRI IV-136 æC Trap macro _HOpen Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word <-- 24 ioRefNum word --> 27 ioPermssn byte --> 28 ioMisc pointer --> 48 ioDirID long word PBHOpen is identical to PBOpen except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing permErr Attempt to open locked file for writing tmfoErr Too many files open æKY PBHOpenRF æFc Files.h æT Function æD pascal OSErr PBHOpenRF(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHOpenRF((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-137 æC Trap macro _HOpenRF Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word <-- 24 ioRefNum word --> 27 ioPermssn byte --> 28 ioMisc pointer --> 48 ioDirID long word PBHOpenRF is identical to PBOpenRF except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing permErr Attempt to open locked file for writing tmfoErr Too many files open æKY PBHOpenDF æFc Files.h æT Function æD pascal OSErr PBHOpenDF(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHOpenDF((HParmBlkPtr) paramBlock,(Boolean) async); æRI VI æC PBHOpenDF creates an access path to the data fork of a file. It is an HFS version of PBOpenDF. æKY PBHCreate æFc Files.h æT Function æD pascal OSErr PBHCreate(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHCreate((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-146 æC Trap macro _HCreate Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 48 ioDirID long word PBHCreate is identical to PBCreate except that it accepts a directory ID in ioDirID. Note: To create a directory instead of a file, call PBDirCreate. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version dirFulErr File directory full dirNFErr Directory not found or incomplete pathname extFSErr External file system ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBHDelete æFc Files.h æT Function æD pascal OSErr PBHDelete(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHDelete((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-147, VI æC Some existing HFS functions now support file IDs as appropriate, but their interface remains stable. This section describes how they accommodate file IDs. FUNCTION PBHDelete (paramBlock: HParamBlkPtr, async: Boolean) : OSErr; If a file ID exists for the file being deleted, the file ID is also deleted. Trap macro _HDelete Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 48 ioDirID long word PBHDelete is identical to PBDelete except that it accepts a directory ID in ioDirID. PBHDelete can be used to delete an empty directory as well. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fBsyErr File busy, directory not empty, or working directory control block open fLckdErr File locked fnfErr File not found nsvErr No such volume ioErr I/O error vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBHRename æFc Files.h æT Function æD pascal OSErr PBHRename(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHRename((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-154, VI æC Some existing HFS functions now support file IDs as appropriate, but their interface remains stable. This section describes how they accommodate file IDs. FUNCTION PBHRename (paramBlock: HParamBlkPtr, async: Boolean) : OSErr; If a file ID exists for the file being renamed, the file ID remains with the file. Trap macro _HRename Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 28 ioMisc pointer --> 48 ioDirID long word PBHRename is identical to PBRename except that it accepts a directory ID in ioDirID and can be used to rename directories as well as files and volumes. Given a pointer to the name of a file or directory in ioNamePtr, PBHRename changes it to the name pointed to by ioMisc. Given a pointer to a volume name in ioNamePtr or a volume reference number in ioVRefNum, it changes the name of the volume to the name pointed to by ioMisc. Warning: PBHRename cannot be used to change the directory a file is in. Result codes noErr No error bdNamErr Bad file name dirFulErr File directory full dirNFErr Directory not found or incomplete pathname dupFNErr Duplicate file name and version extFSErr External file system fLckdErr File locked fnfErr File not found fsRnErr Problem during rename ioErr I/O error nsvErr No such volume paramErr No default volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBHRstFLock æFc Files.h æT Function æD pascal OSErr PBHRstFLock(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHRstFLock((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-152 æC Trap macro _HRstFLock Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 48 ioDirID long word PBHRstFLock is identical to PBRstFLock except that it accepts a directory ID in ioDirID. Result codes noErr No error dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBHSetFLock æFc Files.h æT Function æD pascal OSErr PBHSetFLock(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHSetFLock((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-151 æC Trap macro _HSetFLock Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 48 ioDirID long word PBHSetFLock is identical to PBSetFLock except that it accepts a directory ID in ioDirID. Result codes noErr No error dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBHGetFInfo æFc Files.h æT Function æD pascal OSErr PBHGetFInfo(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHGetFInfo((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-149 æC Trap macro _HGetFileInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word <-> 18 ioNamePtr pointer --> 22 ioVRefNum word <-- 24 ioFRefNum word --> 28 ioFDirIndex word <-- 30 ioFlAttrib byte <-- 32 ioFlFndrInfo 16 bytes <-> 48 ioDirID long word <-- 52 ioFlStBlk word <-- 54 ioFlLgLen long word <-- 58 ioFlPyLen long word <-- 62 ioFlRStBlk word <-- 64 ioFlRLgLen long word <-- 68 ioFlRPyLen long word <-- 72 ioFlCrDat long word <-- 76 ioFlMdDat long word PBHGetFInfo is identical to PBGetFInfo except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume æKY PBHSetFInfo æFc Files.h æT Function æD pascal OSErr PBHSetFInfo(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBHSetFInfo((HParmBlkPtr) paramBlock,(Boolean) async); æRI IV-150 æC Trap macro _HSetFileInfo Parameter block --> 12 ioCompletion pointer <-- 16 ioResult word --> 18 ioNamePtr pointer --> 22 ioVRefNum word --> 32 ioFlFndrInfo 16 bytes --> 48 ioDirID long word --> 72 ioFlCrDat long word --> 76 ioFlMdDat long word PBHSetFInfo is identical to PBSetFInfo except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fLckdErr File locked fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY PBGetAltAccess æFc Files.h æT Function æD pascal OSErr PBGetAltAccess(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBGetAltAccess((HParmBlkPtr) paramBlock,(Boolean) async); æRI VI æC Parameter block Æ 12 ioCompletion long pointer to completion routine ¨ 16 ioResult word result code Æ 18 ioNamePtr long pointer to volume name ¨ 22 ioVRefNum word volume reference number ¨ 32 ioBuffer long pointer to privilege info buffer Æ 36 ioReqCount long size allocated for buffer ¨ 40 ioActCount long amount used in buffer ¨ 44 ioAccessInfo1 long information specific to privilege model ¨ 48 ioAccessInfo2 long information specific to privilege model ¨ 52 ioAccessInfo3 long information specific to privilege model ¨ 56 ioAccessInfo4 long information specific to privilege model Æ 60 ioDirID word parent directory ID PBGetAltAccess retrieves access information from a volume managed by a file system that uses a privilege model different from the AFP model. Result codes <to come> æKY PBSetAltAccess æFc Files.h æT Function æD pascal OSErr PBSetAltAccess(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBSetAltAccess((HParmBlkPtr) paramBlock,(Boolean) async); æRI VI æC Parameter block Æ 12 ioCompletion long pointer to completion routine ¨ 16 ioResult word result code Æ 18 ioNamePtr long pointer to volume name Æ 22 ioVRefNum word volume reference number ¨ 32 ioBuffer long pointer to privilege info buffer Æ 36 ioReqCount long size allocated for buffer ¨ 40 ioActCount long amount used in buffer Æ 44 ioAccessInfo1 long information specific to privilege model Æ 48 ioAccessInfo2 long information specific to privilege model Æ 52 ioAccessInfo3 long information specific to privilege model Æ 56 ioAccessInfo4 long information specific to privilege model Æ 60 ioDirID word parent directory ID PBSetAltAccess modifies access information from a volume managed by a file system that uses a privilege model different from the AFP model. Result codes <to come> æKY PBMakeFSSpec æFc Files.h æT Function æD pascal OSErr PBMakeFSSpec(HParamBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBMakeFSSpec((HParamBlkPtr) paramBlock,(Boolean) async); æC æKY FInitQueue æFc Files.h æT Function æTN A016 æD pascal void FInitQueue(void) = 0xA016; æDT FInitQueue()(void); æRI II-103, IV-128 æC Trap macro _InitQueue FInitQueue clears all queued File Manager calls except the current one. æKY GetFSQHdr æFc Files.h æT Function æD pascal QHdrPtr GetFSQHdr(void); æDT QHdrPtr myVariable = GetFSQHdr()(void); æRI II-125, IV-175 æC You can get a pointer to the header of the file I/O queue by calling the File Manager function GetFSQHdr. FUNCTION GetFSQHdr : QHdrPtr; [Not in ROM] GetFSQHdr returns a pointer to the header of the file I/O queue. Assembly-language note: The global variable FSQHdr contains the header of the file I/O queue. æKY GetDrvQHdr æFc Files.h æT Function æD pascal QHdrPtr GetDrvQHdr(void); æDT QHdrPtr myVariable = GetDrvQHdr()(void); æRI II-128, IV-181 æC You can get a pointer to the header of the drive queue by calling the File Manager function GetDrvQHdr. FUNCTION GetDrvQHdr : QHdrPtr; [Not in ROM] GetDrvQHdr returns a pointer to the header of the drive queue. Assembly-language note: The global variable DrvQHdr contains the header of the drive queue. The drive queue can support any number of drives, limited only by memory space. æKY GetVCBQHdr æFc Files.h æT Function æD pascal QHdrPtr GetVCBQHdr(void); æDT QHdrPtr myVariable = GetVCBQHdr()(void); æRI II-126, IV-178 æC You can get a pointer to the header of the volume-control-block queue by calling the File Manager function GetVCBQHdr. FUNCTION GetVCBQHdr : QHdrPtr; [Not in ROM] GetVCBQHdr returns a pointer to the header of the volume-control-block queue. Assembly-language note: The global variable VCBQHdr contains the header of the volume-control-block-queue. The default volume’s volume control block is pointed to by the global variable DefVCBPtr. æKY HGetVol æFc Files.h æT Function æD pascal OSErr HGetVol(StringPtr volName,short *vRefNum,long *dirID); æDT OSErr myVariable = HGetVol((StringPtr) volName,(short *) vRefNum,(long *) dirID); æRI IV-132, VI æC HGetVol is an HFS version of the MFS function GetVol. It calls the function PBHGetVol, documented in the File Manager chapter of Volume IV. vRefNum can hold a volume reference number or a working directory reference number. dirID holds a directory ID. Trap macro _HGetVol Parameter block —> 12 ioCompletion pointer <— 16 ioResult word <— 18 ioNamePtr pointer <— 22 ioVRefNum word <— 28 ioWDProcID long word <— 32 ioWDVRefNum word <— 48 ioWDDirID long word PBHGetVol returns the default volume and directory last set by either a PBSetVol or a PBHSetVol call. The reference number of the default volume is returned in ioVRefNum. Warning: IOVRefNum will return a working directory reference number (instead of the volume reference number) if, in the last call to PBSetVol or PBHSetVol, a working directory reference number was passed in this field. The volume reference number of the volume on which the default directory exists is returned in ioWDVRefNum. The directory ID of the default directory is returned in ioWDDirID. Result codes noErr No error nsvErr No default volume æKY HSetVol æFc Files.h æT Function æD pascal OSErr HSetVol(StringPtr volName,short vRefNum,long dirID); æDT OSErr myVariable = HSetVol((StringPtr) volName,(short) vRefNum,(long) dirID); æRI IV-133, VI æC HSetVol is an HFS version of the MFS function GetVol. It calls the function PBHGetVol, documented in the File Manager chapter of Volume IV. vRefNum can hold a volume reference number or a working directory reference number. dirID holds a directory ID. <Note: Don’t use HSetVol or PBHSetVol.> æKY HOpen æFc Files.h æT Function æD pascal OSErr HOpen(short vRefNum,long dirID,const Str255 fileName,char permission, short *refNum); æDT OSErr myVariable = HOpen((short) vRefNum,(long) dirID,(const Str255) fileName,(char) permission,( short) * refNum); æRI IV-136, VI æC HOpen creates an access path to the data fork of a file. It is an HFS version of the MFS function Open. It calls the function PBHOpen, documented in the File Manager chapter of Volume IV. Trap macro _HOpen Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word <— 24 ioRefNum word —> 27 ioPermssn byte —> 28 ioMisc pointer —> 48 ioDirID long word PBHOpen is identical to PBOpen except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing permErr Attempt to open locked file for writing tmfoErr Too many files open æKY HOpenRF æFc Files.h æT Function æD pascal OSErr HOpenRF(short vRefNum,long dirID,const Str255 fileName,char permission, short *refNum); æDT OSErr myVariable = HOpenRF((short) vRefNum,(long) dirID,(const Str255) fileName,(char) permission,( short) * refNum); æRI IV-137, VI æC HOpenRF creates an access path to the resource fork of a file. It is an HFS version of the MFS function OpenRF. It calls the function PBHOpenRF, documented in the File Manager chapter of Volume IV. Trap macro _HOpenRF Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word <— 24 ioRefNum word —> 27 ioPermssn byte —> 28 ioMisc pointer —> 48 ioDirID long word PBHOpenRF is identical to PBOpenRF except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume opWrErr File already open for writing permErr Attempt to open locked file for writing tmfoErr Too many files open æKY AllocContig æFc Files.h æT Function æD pascal OSErr AllocContig(short refNum,long *count); æDT OSErr myVariable = AllocContig((short) refNum,(long *) count); æRT 218 æRI IV-143, VI æC AllocContig is a high-level function that calls PBAllocContig. Trap macro _AllocContig Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 24 ioRefNum word —> 36 ioReqCount long word <— 40 ioActCount long word PBAllocContig is identical to PBAllocate except that if there isn’t enough contiguous empty space on the volume to satisfy the allocation request, PBAllocContig will do nothing and will return dskFulErr as its function result. If you want to allocate whatever space is available, even when the entire request cannot be filled as a contiguous piece, call PBAllocate instead. Result codes noErr No error dskFulErr Disk full fLckdErr File locked fnOpnErr File not open ioErr I/O error rfNumErr Bad reference number vLckdErr Software volume lock wPrErr Hardware volume lock wrPermErr Read/write permission doesn’t allow writing æKY HCreate æFc Files.h æT Function æD pascal OSErr HCreate(short vRefNum,long dirID,const Str255 fileName,OSType creator, OSType fileType); æDT OSErr myVariable = HCreate((short) vRefNum,(long) dirID,(const Str255) fileName,(OSType) creator,() OSType fileType); æRT 218 æRI IV-146, VI æC HCreate creates a new file and sets the type and creator. It is an HFS version of the MFS function Create. vRefNum can hold a volume reference number or a working directory reference number. dirID holds a directory ID. HCreate calls the function PBHCreate, documented in the File Manager chapter of Volume IV. Trap macro _HCreate Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word —> 48 ioDirID long word PBHCreate is identical to PBCreate except that it accepts a directory ID in ioDirID. Note: To create a directory instead of a file, call PBDirCreate. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version dirFulErr File directory full dirNFErr Directory not found or incomplete pathname extFSErr External file system ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY DirCreate æFc Files.h æT Function æD pascal OSErr DirCreate(short vRefNum,long parentDirID,const Str255 directoryName, long *createdDirID); æDT OSErr myVariable = DirCreate((short) vRefNum,(long) parentDirID,(const Str255) directoryName,( long) * createdDirID); æRT 218 æRI IV-146, VI æC DirCreate is a high-level function that calls PBDirCreate. Trap macro _DirCreate Parameter block —> 12 ioCompletion pointer <— 16 ioResult word <–> 18 ioNamePtr pointer —> 22 ioVRefNum word <–> 48 ioDirID long word PBDirCreate is identical to PBHCreate except that it creates a new directory instead of a file. You can specify the parent of the directory to be created in ioDirID; if it’s 0, the new directory will be placed in the root directory. The directory ID of the new directory is returned in ioDirID. Warning: PBDirCreate operates only with the hierarchical version of the File Manager; if used on a Macintosh equipped only with the 64K ROM version of the File Manager, it will generate a system error. Result codes noErr No error bdNamErr Bad file name dupFNErr Duplicate file name and version dirFulErr File directory full dirNFErr Directory not found or incomplete pathname extFSErr External file system ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY HDelete æFc Files.h æT Function æD pascal OSErr HDelete(short vRefNum,long dirID,const Str255 fileName); æDT OSErr myVariable = HDelete((short) vRefNum,(long) dirID,(const Str255) fileName); æRI IV-147, VI æC HDelete removes a closed file. It is an HFS version of the MFS function Delete. vRefNum can hold a volume reference number or a working directory reference number. dirID holds a directory ID. HDelete calls the function PBHDelete, documented in the File Manager chapter of Volume IV. Trap macro _HDelete Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word —> 48 ioDirID long word PBHDelete is identical to PBDelete except that it accepts a directory ID in ioDirID. PBHDelete can be used to delete an empty directory as well. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fBsyErr File busy, directory not empty, or working directory control block open fLckdErr File locked fnfErr File not found nsvErr No such volume ioErr I/O error vLckdErr Software volume lock wPrErr Hardware volume lock æKY HGetFInfo æFc Files.h æT Function æD pascal OSErr HGetFInfo(short vRefNum,long dirID,const Str255 fileName,FInfo *fndrInfo); æDT OSErr myVariable = HGetFInfo((short) vRefNum,(long) dirID,(const Str255) fileName,(FInfo *) fndrInfo); æRI IV-149 æC Trap macro _HGetFileInfo Parameter block —> 12 ioCompletion pointer <— 16 ioResult word <–> 18 ioNamePtr pointer —> 22 ioVRefNum word <— 24 ioFRefNum word —> 28 ioFDirIndex word <— 30 ioFlAttrib byte <— 32 ioFlFndrInfo 16 bytes <–> 48 ioDirID long word <— 52 ioFlStBlk word <— 54 ioFlLgLen long word <— 58 ioFlPyLen long word <— 62 ioFlRStBlk word <— 64 ioFlRLgLen long word <— 68 ioFlRPyLen long word <— 72 ioFlCrDat long word <— 76 ioFlMdDat long word PBHGetFInfo is identical to PBGetFInfo except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume æKY HSetFInfo æFc Files.h æT Function æD pascal OSErr HSetFInfo(short vRefNum,long dirID,const Str255 fileName,const FInfo *fndrInfo); æDT OSErr myVariable = HSetFInfo((short) vRefNum,(long) dirID,(const Str255) fileName,(const FInfo *) fndrInfo); æRI IV-150 æC Trap macro _HSetFileInfo Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word —> 32 ioFlFndrInfo 16 bytes —> 48 ioDirID long word —> 72 ioFlCrDat long word —> 76 ioFlMdDat long word PBHSetFInfo is identical to PBSetFInfo except that it accepts a directory ID in ioDirID. Result codes noErr No error bdNamErr Bad file name dirNFErr Directory not found or incomplete pathname extFSErr External file system fLckdErr File locked fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY HSetFLock æFc Files.h æT Function æD pascal OSErr HSetFLock(short vRefNum,long dirID,const Str255 fileName); æDT OSErr myVariable = HSetFLock((short) vRefNum,(long) dirID,(const Str255) fileName); æRI IV-151, VI æC HSetFLock locks a file: no new access paths to it can be created. It is an HFS version of the MFS function SetFLock. It calls the function PBHSetFLock, documented in the File Manager chapter of Volume IV. Trap macro _HSetFLock Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word —> 48 ioDirID long word PBHSetFLock is identical to PBSetFLock except that it accepts a directory ID in ioDirID. Result codes noErr No error dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY HRstFLock æFc Files.h æT Function æD pascal OSErr HRstFLock(short vRefNum,long dirID,const Str255 fileName); æDT OSErr myVariable = HRstFLock((short) vRefNum,(long) dirID,(const Str255) fileName); æRI IV-152, VI æC HRstFLock unlocks a file. It is an HFS version of the MFS function RstFLock. It calls the function PBHRstFLock, documented in the File Manager chapter of Volume IV. Trap macro _HRstFLock Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word —> 48 ioDirID long word PBHRstFLock is identical to PBRstFLock except that it accepts a directory ID in ioDirID. Result codes noErr No error dirNFErr Directory not found or incomplete pathname extFSErr External file system fnfErr File not found ioErr I/O error nsvErr No such volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY HRename æFc Files.h æT Function æD pascal OSErr HRename(short vRefNum,long dirID,const Str255 oldName,const Str255 newName); æDT OSErr myVariable = HRename((short) vRefNum,(long) dirID,(const Str255) oldName,(const Str255) newName); æRI IV-154, VI æC HRename changes the name of a file or directory. It is an HFS version of the MFS function Rename. It calls the function PBHRename, documented in the File Manager chapter of Volume IV. Trap macro _Rename Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word —> 26 ioVersNum byte —> 28 ioMisc pointer Given a pointer to a file name in ioNamePtr (and on flat volumes, a version number in ioVersNum), PBRename changes the name of the file to the name pointed to by ioMisc. (If the name pointed to by ioNamePtr contains one or more colons, so must the name pointed to by ioMisc.) Access paths currently in use aren’t affected. Given a pointer to a volume name in ioNamePtr or a volume reference number in ioVRefNum, it changes the name of the volume to the name pointed to by ioMisc. If a volume to be renamed is specified by its volume reference number, ioNamePtr can be NIL. Warning: If a volume to be renamed is specified by its volume name, be sure that it ends with a colon, or Rename will consider it a file name. Result codes noErr No error bdNamErr Bad file name dirFulErr File directory full dupFNErr Duplicate file name and version extFSErr External file system fLckdErr File locked fnfErr File not found fsRnErr Problem during rename ioErr I/O error nsvErr No such volume paramErr No default volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY CatMove æFc Files.h æT Function æD pascal OSErr CatMove(short vRefNum,long dirID,const Str255 oldName,long newDirID, const Str255 newName); æDT OSErr myVariable = CatMove((short) vRefNum,(long) dirID,(const Str255) oldName,(long) newDirID,( const) Str255 newName); æRT 218 æRI IV-157, VI æC CatMove is a high-level function that calls PBCatMove. Trap macro _CatMove Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer —> 22 ioVRefNum word —> 28 ioNewName pointer —> 36 ioNewDirID long word —> 48 ioDirID long word PBCatMove moves files or directories from one directory to another. The name of the file or directory to be moved is pointed to by ioNamePtr; ioVRefNum contains either the volume reference number or working directory reference number. A directory ID can be specified in ioDirID. The name and directory ID of the directory to which the file or directory is to be moved are specified by ioNewName and ioNewDirID. PBCatMove is strictly a file catalog operation; it does not actually change the location of the file or directory on the disk. PBCatMove cannot move a file or directory to another volume (that is, ioVRefNum is used in specifying both the source and the destination). It also cannot be used to rename files or directories; for that, use PBHRename. Result codes noErr No error badMovErr Attempt to move into offspring bdNamErr Bad file name or attempt to move into a file dupFNErr Duplicate file name and version fnfErr File not found ioErr I/O error nsvErr No such volume paramErr No default volume vLckdErr Software volume lock wPrErr Hardware volume lock æKY OpenWD æFc Files.h æT Function æD pascal OSErr OpenWD(short vRefNum,long dirID,long procID,short *wdRefNum); æDT OSErr myVariable = OpenWD((short) vRefNum,(long) dirID,(long) procID,(short *) wdRefNum); æRT 218 æRI IV-158, VI æC OpenWD is a high-level function that calls PBOpenWD. Trap macro _OpenWD Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 18 ioNamePtr pointer <–> 22 ioVRefNum word —> 28 ioWDProcID long word —> 48 ioWDDirID long word PBOpenWD takes the directory specified by ioVRefNum, ioWDDirID, and ioWDProcID and makes it a working directory. (You can also specify the directory using a combination of partial pathname and directory ID.) It returns a working directory reference number in ioVRefNum that can be used in subsequent calls. If a given directory has already been made a working directory using the same ioWDProcID, no new working directory will be opened; instead, the existing working directory reference number will be returned. If a given directory was already made a working directory using a different ioWDProcID, a new working directory reference number is returned. Result codes noErr No error tmwdoErr Too many working directories open æKY CloseWD æFc Files.h æT Function æD pascal OSErr CloseWD(short wdRefNum); æDT OSErr myVariable = CloseWD((short) wdRefNum); æRT 218 æRI IV-158, VI æC CloseWD is a high-level function that calls PBCloseWD. Trap macro _CloseWD Parameter block —> 12 ioCompletion pointer <— 16 ioResult word —> 22 ioVRefNum word PBCloseWD releases the working directory whose working directory reference number is specified in ioVRefNum. Note: If a volume reference number is specified in ioVRefNum, PBCloseWD does nothing. Result codes noErr No error nsvErr No such volume æKY GetWDInfo æFc Files.h æT Function æD pascal OSErr GetWDInfo(short wdRefNum,short *vRefNum,long *dirID,long *procID); æDT OSErr myVariable = GetWDInfo((short) wdRefNum,(short *) vRefNum,(long *) dirID,(long *) procID); æRT 218 æRI IV-159, VI æC GetWDInfo is a high-level function that calls PBGetWDInfo. Trap macro _GetWDInfo Parameter block —> 12 ioCompletion pointer <— 16 ioResult word <— 18 ioNamePtr pointer <–> 22 ioVRefNum word —> 26 ioWDIndex word <–> 28 ioWDProcID long word <–> 32 ioWDVRefNum word <— 48 ioWDDirID long word PBGetWDInfo returns information about the specified working directory. The working directory can be specified either by its working directory reference number in ioVRefNum (in which case ioWDIndex should be 0), or by its index number in ioWDIndex. In the latter case, if ioVRefNum is nonzero, it’s interpreted as a volume specification (volume reference number or drive number), and only working directories on that volume are indexed. IOWDVRefNum always returns the volume reference number. IOVRefNum returns a working directory reference number when a working directory reference number is passed in that field; otherwise, it returns a volume reference number. The volume name is returned in ioNamePtr. If IOWDProcID is nonzero, only working directories with that identifier are indexed; otherwise all working directories are indexed. Result codes noErr No error nsvErr No such volume æKY PBExchangeFiles æFc Files.h æT Function æD pascal OSErr PBExchangeFiles(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBExchangeFiles((HParmBlkPtr) paramBlock,(Boolean) async); æC Parameter Block ¨ 16 ioResult word Æ 18 ioNamePtr string pointer Æ 22 ioVRefNum word Æ 28 ioDestNamePtr string pointer Æ 36 ioDestDirID long Æ 48 ioSrcDirID long You should use PBExchangeFiles if your application needs to preserve the file ID after moving the data into a new file. Typically, you use PBExchangeFiles after creating a new file during a safe save. You must specify both files, which must exist on the same volume. The file specified by [ioDestDirID, ioDestNamePtr] is exchanged with the file specified by [ioSrcDirID, ioNamePtr]. Both forks of the files are exchanged. Modification dates in the catalog record are exchanged, along with the fields accessed by HFS to locate the data of the files. All other catalog information remains unchanged. PBExchangeFiles works on either open or closed files. If either file is open, PBExchangeFiles updates any file control blocks associated with the file. PBExchangeFiles does not require that file IDs exist for the files being exchanged. Result codes: extFSErr -58 External file system ioErr -36 I/O error nsvErr -35 No such volume fnfErr -43 File not found fLckdErr -45 One or both files locked volOfflinErr -53 Volume is off-line wrgVolTypeErr -123 Not an HFS volume fidNotFoundErr -1300 File not found fidExists -1301 File ID already exists notAFileErr -1302 Specified file is a directory diffVolErr -xxxx Volume specifications in pathnames are not equivalent æKY PBCreateFileID æFc Files.h æT Function æD pascal OSErr PBCreateFileID(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBCreateFileID((HParmBlkPtr) paramBlock,(Boolean) async); æC Parameter Block ¨ 16 ioResult word Æ 18 ioNamePtr string pointer Æ 22 ioVRefNum word Æ 48 ioSrcDirID long ¨ 54 ioFileID long Given a volume reference number, file name, and parent directory ID, PBCreateFileID creates a record to hold the name and parent directory ID of the specified file. The actual value of the file ID is the same as the file number stored in the file record. If a file ID already exists for the file, the ID value is returned in ioFileID. Result codes extFSErr -58 External file system ioErr -36 I/O error nsvErr -35 No such volume volOfflinErr -53 Volume is offline vLckdErr -46 Software volume lock wPrErr -44 Hardware volume lock wrgVolTypeErr -123 Not an HFS volume fidNotFoundErr -1300 File not found fidExists -1301 File ID already exists notAFileErr -1302 Specified file is a directory æKY PBResolveFileID æFc Files.h æT Function æD pascal OSErr PBResolveFileID(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBResolveFileID((HParmBlkPtr) paramBlock,(Boolean) async); æC Parameter Block ¨ 16 ioResult word ´ 18 ioNamePtr string pointer Æ 22 ioVRefNum word ¨ 48 ioSrcDirID long Æ 54 ioFileID long PBResolveFileID returns the filename and parent directory ID of the file referred to by file ID in the ioFileID field. It places the filename in the string pointed to by ioNamePtr and the directory ID in ioSrcDirID. You must allocate memory <how much?> for the string before you make the call. If the name string is NIL, PBResolveFileID returns only the parent directory ID. If the name string is not NIL but is only a volume name, PBResolveFileID ignores the value in ioVRefNum, uses the volume name instead, and overwrites the name string with the filename. A return code of fidNotFound means that the specified file ID has become invalid either because the file was deleted or the file ID was destroyed by PBDeleteFileID. Result codes: extFSErr -58 External file system ioErr -36 I/O error nsvErr -35 No such volume volOfflinErr -53 Volume is off-line wrgVolTypeErr -123 Not an HFS volume fidNotFoundErr -1300 File ID not found fidExists -1301 File ID already exists notAFileErr -1302 Specified file is a directory æKY PBDeleteFileID æFc Files.h æT Function æD pascal OSErr PBDeleteFileID(HParmBlkPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDeleteFileID((HParmBlkPtr) paramBlock,(Boolean) async); æC Parameter Block ¨ 16 ioResult word Æ 18 ioNamePtr string pointer Æ 22 ioVRefNum word Æ 54 ioFileID long PBDeleteFileID invalidates a file ID on the volume specified by ioVRefNum or ioNamePtr. After it has invalidated a file ID, the File Manager can no longer resolve it to a filename and parent directory ID. The file ID is invalidated whether or not the target file referenced by that ID still exists. Result codes: extFSErr -58 External file system ioErr -36 I/O error nsvErr -35 No such volume volOfflinErr -53 Volume is offline vLckdErr -46 Software volume lock wPrErr -44 Hardware volume lock wrgVolTypeErr -123 Not an HFS volume fidNotFoundErr -1300 File ID not found fidExists -1301 File ID already exists notAFileErr -1302 Specified file is a directory æKY PBDTGetPath æFc Files.h æT Function æD pascal OSErr PBDTGetPath(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTGetPath((DTPBPtr) paramBlock,(Boolean) async); æC æKY PBDTCloseDown æFc Files.h æT Function æD pascal OSErr PBDTCloseDown(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTCloseDown((DTPBPtr) paramBlock,(Boolean) async); æC æKY PBDTAddIcon æFc Files.h æT Function æD pascal OSErr PBDTAddIcon(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTAddIcon((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTGetIcon æFc Files.h æT Function æD pascal OSErr PBDTGetIcon(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTGetIcon((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTGetIconInfo æFc Files.h æT Function æD pascal OSErr PBDTGetIconInfo(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTGetIconInfo((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTAddAPPL æFc Files.h æT Function æD pascal OSErr PBDTAddAPPL(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTAddAPPL((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTRemoveAPPL æFc Files.h æT Function æD pascal OSErr PBDTRemoveAPPL(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTRemoveAPPL((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTGetAPPL æFc Files.h æT Function æD pascal OSErr PBDTGetAPPL(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTGetAPPL((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTSetComment æFc Files.h æT Function æD pascal OSErr PBDTSetComment(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTSetComment((DTPBPtr) paramBlock,(Boolean) async); æC æKY PBDTRemoveComment æFc Files.h æT Function æD pascal OSErr PBDTRemoveComment(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTRemoveComment((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTGetComment æFc Files.h æT Function æD pascal OSErr PBDTGetComment(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTGetComment((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTFlush æFc Files.h æT Function æD pascal OSErr PBDTFlush(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTFlush((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTReset æFc Files.h æT Function æD pascal OSErr PBDTReset(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTReset((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTGetInfo æFc Files.h æT Function æD pascal OSErr PBDTGetInfo(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTGetInfo((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTOpenInform æFc Files.h æT Function æD pascal OSErr PBDTOpenInform(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTOpenInform((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY PBDTDelete æFc Files.h æT Function æD pascal OSErr PBDTDelete(DTPBPtr paramBlock,Boolean async); æDT OSErr myVariable = PBDTDelete((DTPBPtr) paramBlock,(Boolean) async); æRI æC æKY MakeFSSpec æFc Files.h æT Function æD /* FSSpec Glue */ pascal OSErr MakeFSSpec(short vRefNum,long dirID,StringPtr fileName); æDT /* FSSpec Glue */ pascal OSErr myVariable = MakeFSSpec((short) vRefNum,(long) dirID,(StringPtr) fileName); æRI VI æC You use the MakeFSSpec function to establish the canonical form of the name for a file, folder, or volume. FUNCTION MakeFSSpec (vRefNum: Integer; dirID: LongInt; fileName: Str255; VAR canonicalFile: CanonicalFileSpec) : OSErr; MakeFSSpec places the canonical form of the specified file reference in the CanonicalFileSpec parameter. (See “Identifying Files, Folders, and Volumes” for a description of the FSSpec record.) The vRefNum parameter is the volume reference number, a working directory reference number, a drive number, or 0 for the default volume. The dirID parameter is the parent directory ID of the target object. If the directory is sufficiently specified by either vRefNum or fileName, dirID can be 0. If you explicitly specify dirID (that is, if it is any value other than 0), and if vRefNum is a working directory reference number, dirID overrides the directory ID included in vRefNum. The fileName parameter is a full or partial pathname. If it is a full pathname, MakeFSSpec ignores vRefNum and dirID. A partial pathname might identify only the final target, or it might include one or more parent folder names. If fileName is a partial pathname, vRefNum, dirID, or both must be valid. You can pass the input to MakeFSSpec in any of the four ways described in “Identifying Files, Folders, and Volumes” earlier in this chapter. See “Using the File Manager” for a summary of the how MakeFSSpec accepts input and how it fills in the FSSpec record for files, folders, and volumes. In addition to the result code listed here, MakeFSSpec can return a number of different File Manager or Memory Manager error codes. Result codes paramErr -50 Output is NIL æKY FSpOpenDF æFc Files.h æT Function æD pascal OSErr FSpOpenDF(FSSpecPtr spec,char permission,short *refNum); æDT OSErr myVariable = FSpOpenDF((FSSpecPtr) spec,(char) permission,(short *) refNum); æRI æC æKY FSpOpenRF æFc Files.h æT Function æD pascal OSErr FSpOpenRF(FSSpecPtr spec,char permission,short *refNum); æDT OSErr myVariable = FSpOpenRF((FSSpecPtr) spec,(char) permission,(short *) refNum); æRI æC æKY FSpCreate æFc Files.h æT Function æD pascal OSErr FSpCreate(FSSpecPtr spec,OSType creator,OSType fileType); æDT OSErr myVariable = FSpCreate((FSSpecPtr) spec,(OSType) creator,(OSType) fileType); æRI æC æKY FSpDirCreate æFc Files.h æT Function æD pascal OSErr FSpDirCreate(FSSpecPtr spec,long *createdDirID); æDT OSErr myVariable = FSpDirCreate((FSSpecPtr) spec,(long *) createdDirID); æRI æC æKY FSpDelete æFc Files.h æT Function æD pascal OSErr FSpDelete(FSSpecPtr spec); æDT OSErr myVariable = FSpDelete((FSSpecPtr) spec); æRI æC æKY FSpGetFInfo æFc Files.h æT Function æD pascal OSErr FSpGetFInfo(FSSpecPtr spec,FInfo *fndrInfo); æDT OSErr myVariable = FSpGetFInfo((FSSpecPtr) spec,(FInfo *) fndrInfo); æRI æC æKY FSpSetFInfo æFc Files.h æT Function æD pascal OSErr FSpSetFInfo(FSSpecPtr spec,FInfo *fndrInfo); æDT OSErr myVariable = FSpSetFInfo((FSSpecPtr) spec,(FInfo *) fndrInfo); æRI æC æKY FSpSetFLock æFc Files.h æT Function æD pascal OSErr FSpSetFLock(FSSpecPtr spec); æDT OSErr myVariable = FSpSetFLock((FSSpecPtr) spec); æRI æC æKY FSpRstFLock æFc Files.h æT Function æD pascal OSErr FSpRstFLock(FSSpecPtr spec); æDT OSErr myVariable = FSpRstFLock((FSSpecPtr) spec); æRI æC æKY FSpRename æFc Files.h æT Function æD pascal OSErr FSpRename(FSSpecPtr spec,StringPtr newName); æDT OSErr myVariable = FSpRename((FSSpecPtr) spec,(StringPtr) newName); æRI æC æKY FSpCatMove æFc Files.h æT Function æD pascal OSErr FSpCatMove(FSSpecPtr source,FSSpecPtr dest); æDT OSErr myVariable = FSpCatMove((FSSpecPtr) source,(FSSpecPtr) dest); æRI æC æKY FSpOpenResFile æFc Files.h æT Function æD pascal short FSpOpenResFile(FSSpecPtr spec,char permission); æDT short myVariable = FSpOpenResFile((FSSpecPtr) spec,(char) permission); æRI æC æKY FSpCreateResFile æFc Files.h æT Function æD pascal void FSpCreateResFile(FSSpecPtr spec); æDT FSpCreateResFile((FSSpecPtr) spec); æRI æC æKY FixMath.h æKL Fix2Frac Fix2Long Fix2X FixATan2 FixDiv Frac2Fix Frac2X FracCos FracDiv FracMul FracSin FracSqrt Long2Fix X2Fix X2Frac æKY Fix2Frac æFc FixMath.h æT Function æTN A841 æD pascal Fract Fix2Frac(Fixed x) = 0xA841; æDT Fract myVariable = Fix2Frac((Fixed) x); æRI IV-65 æC Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between fixed-point types. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY Fix2Long æFc FixMath.h æT Function æTN A840 æD pascal long Fix2Long(Fixed x) = 0xA840; æDT long myVariable = Fix2Long((Fixed) x); æRI IV-65 æC Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between fixed-point types. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY FixATan2 æFc FixMath.h æT Function æTN A818 æD pascal Fixed FixATan2(long x,long y) = 0xA818; æDT Fixed myVariable = FixATan2((long) x,(long) y); æRI IV-65 æC FixATan2 returns the arctangent of y / x in radians. Note that FixATan2 effects “arctan(type / type) --> Fixed”: arctan(LONGINT / LONGINT) --> Fixed arctan(Fixed / Fixed) --> Fixed arctan(Fract / Fract) --> Fixed æKY Long2Fix æFc FixMath.h æT Function æTN A83F æD pascal Fixed Long2Fix(long x) = 0xA83F; æDT Fixed myVariable = Long2Fix((long) x); æRI IV-65 æC Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between fixed-point types. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY Frac2Fix æFc FixMath.h æT Function æTN A842 æD pascal Fixed Frac2Fix(Fract x) = 0xA842; æDT Fixed myVariable = Frac2Fix((Fract) x); æRI IV-65 æC Long2Fix, Fix2Long, Fix2Frac, and Frac2Fix convert between fixed-point types. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY Frac2X æFc FixMath.h æT Function æD pascal extended Frac2X(Fract x); æDT extended myVariable = Frac2X((Fract) x); æRI IV-65 æC Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract and the Extended floating-point type. These functions do not set floating-point exception flags. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY Fix2X æFc FixMath.h æT Function æD pascal extended Fix2X(Fixed x); æDT extended myVariable = Fix2X((Fixed) x); æRI IV-65 æC Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract and the Extended floating-point type. These functions do not set floating-point exception flags. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY X2Fix æFc FixMath.h æT Function æD pascal Fixed X2Fix(extended x); æDT Fixed myVariable = X2Fix((extended) x); æRI IV-65 æC Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract and the Extended floating-point type. These functions do not set floating-point exception flags. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY X2Frac æFc FixMath.h æT Function æD pascal Fract X2Frac(extended x); æDT Fract myVariable = X2Frac((extended) x); æRI IV-65 æC Fix2X, X2Fix, Frac2X, and X2Frac convert between Fixed and Fract and the Extended floating-point type. These functions do not set floating-point exception flags. Examples Examples of the use of these fixed-point functions are provided below; all numbers are decimal unless otherwise noted. Function Result Comment FixDiv (X2Fix(1.95), X2Fix(1.30)) $00018000 1.5 = 01.10 bin FracDiv (X2Frac(1.95), X2Frac(1.30)) $60000000 1.5 = 01.10 bin FracMul (X2Frac(1.50), X2Frac(1.30)) $7CCCCCCD 1.95 rounded FracSqrt (X2Frac(1.96)) $5999999A 1.4 rounded FracSin (X2Fix(3.1416015625)) $00000000 0 FracCos (X2Fix(3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(1.75)) $00000002 2 Fix2Frac (X2Fix(1.75)) $70000000 1.75 = 01.11 bin Frac2Fix (X2Frac(1.75)) $0001C000 1.75 = 01.11 bin FixATan2 (X2Fix(1.00), X2Fix(1.00)) $0000C910 0.C910 hex = X2Fix (π/4) FixDiv (X2Fix(-1.95), X2Fix(1.30)) $FFFE8000 -1.5 FracDiv (X2Frac(-1.95), X2Frac(1.30)) $A0000000 -1.5 FracMul (X2Frac(-1.50), X2Frac(1.30)) $83333333 -1.95 rounded FracSin (X2Fix(-3.1416015625)) $00000000 0 FracCos (X2Fix(-3.1416015625)) $C0000000 -1 Fix2Long (X2Fix(-1.75)) $FFFFFFFE -2 Fix2Frac (X2Fix(-1.75)) $90000000 -1.75 Frac2Fix (X2Frac(-1.75)) $FFFE4000 -1.75 FixATan2 (X2Fix(-1.00), X2Fix(-1.00)) $FFFDA4D0 -3*X2Fix(π/4)=3*0.C910 hex æKY FracMul æFc FixMath.h æT Function æTN A84A æD pascal Fract FracMul(Fract x,Fract y) = 0xA84A; æDT Fract myVariable = FracMul((Fract) x,(Fract) y); æRI IV-64 æC FracMul returns x * y. Note that FracMul effects “type * Fract --> type”: Fract * Fract --> Fract LONGINT * Fract --> LONGINT Fract * LONGINT --> LONGINT Fixed * Fract --> Fixed Fract * Fixed --> Fixed æKY FixDiv æFc FixMath.h æT Function æTN A84D æD pascal Fixed FixDiv(Fixed x,Fixed y) = 0xA84D; æDT Fixed myVariable = FixDiv((Fixed) x,(Fixed) y); æRI IV-64 æC FixDiv returns x / y. Note that FixDiv effects “type / type --> Fixed” and “type / Fixed --> type”: Fixed / Fixed --> Fixed LONGINT / LONGINT --> Fixed Fract / Fract --> Fixed LONGINT / Fixed --> LONGINT Fract / Fixed --> Fract æKY FracDiv æFc FixMath.h æT Function æTN A84B æD pascal Fract FracDiv(Fract x,Fract y) = 0xA84B; æDT Fract myVariable = FracDiv((Fract) x,(Fract) y); æRI IV-64 æC FracDiv returns x / y. Note that FracDiv effects “type / type --> Fract” and “type / Fract --> type”: Fract / Fract --> Fract LONGINT / LONGINT --> Fract Fixed / Fixed --> Fract LONGINT / Fract --> LONGINT Fixed / Fract --> Fixed æKY FracSqrt æFc FixMath.h æT Function æTN A849 æD pascal Fract FracSqrt(Fract x) = 0xA849; æDT Fract myVariable = FracSqrt((Fract) x); æRI IV-64 æC FracSqrt returns the square root of x, with x interpreted as unsigned in the range 0 through 4–(2–30), inclusive: That is, bit 15 in Figure 1 has weight 2 rather than –2. The result, too, is unsigned in the range 0 through 2, inclusive. æKY FracSin æFc FixMath.h æT Function æTN A848 æD pascal Fract FracSin(Fixed x) = 0xA848; æDT Fract myVariable = FracSin((Fixed) x); æRI IV-64 æC FracCos and FracSin return the cosine and sine of their radian arguments, respectively. The hexadecimal value 0.C910 (which is FixATan2(1,1)) is the approximation to π/4 used for argument reduction. Thus, FracCos and FracSin are nearly periodic, but with period 2*P instead of 2*π, where P=3.1416015625 and π, of course, is 3.14159265.... æKY FracCos æFc FixMath.h æT Function æTN A847 æD pascal Fract FracCos(Fixed x) = 0xA847; æDT Fract myVariable = FracCos((Fixed) x); æRI IV-64 æC FracCos and FracSin return the cosine and sine of their radian arguments, respectively. The hexadecimal value 0.C910 (which is FixATan2(1,1)) is the approximation to π/4 used for argument reduction. Thus, FracCos and FracSin are nearly periodic, but with period 2*P instead of 2*π, where P=3.1416015625 and π, of course, is 3.14159265.... æKY Float.h æFc Float.h æD Synopsis #define DBL_DIG 15 #define DBL_EPSILO (scalb(-52,1.0)) #define DBL_MANT_DIG 53 #define DBL_MAX (nextdouble(inf(),0.0)) #define DBL_MAX_10_EXP 308 #define DBL_MAX_EXP 1024 #define DBL_MI (scalb(DBL_MIN_EXP-1,1.0)) #define DBL_MIN_10_EXP (-307) #define DBL_MIN_EXP (-1021) #define FLT_DIG 7 #define FLT_EPSILO (scalb(-23,1.0)) #define FLT_MANT_DIG 24 #define FLT_MAX (nextfloat(inf(),0.0)) #define FLT_MAX_10_EXP 38 #define FLT_MAX_EXP 128 #define FLT_MI (scalb(FLT_MIN_EXP-1,1.0)) #define FLT_MIN_10_EXP (-37) #define FLT_MIN_EXP (-125) #define FLT_RADIX 2 #define FLT_ROUNDS ((getround()+1) % 4) #define LDBL_DIG 19 #define LDBL_EPSILO (scalb(-63,1.0)) #define LDBL_MANT_DIG 64 #define LDBL_MAX (nextextended(inf(),0.0)) #define LDBL_MAX_10_EXP 4932 #define LDBL_MAX_EXP 16384 #define LDBL_MI (scalb(LDBL_MIN_EXP-1,1.0)) #define LDBL_MIN_10_EXP (-4931) #define LDBL_MIN_EXP (-16382) æC Description The header <Float.h> specifies the characteristics of floating types float, double, and long double. The functions scalb, nextfloat, nextround, and nextextended, used in the macros above, are declared in <SANE.h>. See also Apple Numerics Manual, 2nd edition æKY Folders.h æKL FindFolder kAppleMenuFolderType kControlPanelFolderType kCreateFolder kDesktopFolderType kDontCreateFolder kExtensionFolderType kOnSystemDisk kPreferencesFolderType kSpoolFolderType kStartupFolderType kSystemFolderType kTemporaryFolderType kTrashFolderType kWhereToEmptyTrashFolderType æKY kOnSystemDisk æFc Folders.h æT #define æD #define kOnSystemDisk 0x8000 æC æKY kCreateFolder æFc Folders.h æT #define æD #define kCreateFolder TRUE æC æKY kDontCreateFolder æFc Folders.h æT #define æD #define kDontCreateFolder FALSE æC æKY kSystemFolderType æFc Folders.h æT #define æD #define kSystemFolderType 'macs' /*the system folder*/ æC æKY kDesktopFolderType æFc Folders.h æT #define æD #define kDesktopFolderType 'desk' /*the desktop folder; objects in this folder show on the desk top.*/ æC æKY kTrashFolderType æFc Folders.h æT #define æD #define kTrashFolderType 'trsh' /*the trash folder; objects in this folder show up in the trash*/ æC æKY kWhereToEmptyTrashFolderType æFc Folders.h æT #define æD #define kWhereToEmptyTrashFolderType 'empt' /*the "empty trash" folder; Finder starts empty from here down*/ æC æKY kSpoolFolderType æFc Folders.h æT #define æD #define kSpoolFolderType 'spoo' /*spool files go here (from the print drivers to the despooler*/ æC æKY kStartupFolderType æFc Folders.h æT #define æD #define kStartupFolderType 'strt' /*Finder objects (applications, documents, DAs, aliases, to...) to open at startup go here*/ æC æKY kAppleMenuFolderType æFc Folders.h æT #define æD #define kAppleMenuFolderType 'amnu' /*Finder objects to put into the Apple menu go here*/ æC æKY kControlPanelFolderType æFc Folders.h æT #define æD #define kControlPanelFolderType 'ctrl' /*Control Panels go here (may contain INITs)*/ æC æKY kExtensionFolderType æFc Folders.h æT #define æD #define kExtensionFolderType 'extn' /*Finder extensions go here*/ æC æKY kPreferencesFolderType æFc Folders.h æT #define æD #define kPreferencesFolderType 'pref' /*preferences for applications go here*/ æC æKY kTemporaryFolderType æFc Folders.h æT #define æD #define kTemporaryFolderType 'temp' /*temporary files go here (deleted periodically, but don't rely on it.)*/ æC æKY FindFolder æFc Folders.h æT Function æD pascal OSErr FindFolder(short vRefNum,OSType folderType,Boolean createFolder, short *foundVRefNum,long *foundDirID) = {0x7000,0xA823}; æDT OSErr myVariable = FindFolder((short) vRefNum,(OSType) folderType,(Boolean) createFolder,( short) * foundVRefNum,(long *) foundDirID); æC You can call the FindFolder function to get the path information so that you can access special folders. You pass FindFolder a target volume and a constant that tells it which special folder you are interested in. FindFolder returns a volume reference number and a directory ID. If the specified folder does not exist, FindFolder can create it and return the new directory ID. The Finder identifies the folder types and their names in a resource of type 'fld#'. Table 8-2 lists the folder types in version 7.0, their resource types, and the constants that represent them. Table 8-2. Special folders Folder Type Constant System Folder 'macs' kSystemFolderType Extensions folder 'extn' kExtensionFolderType Preferences folder 'pref' kPreferencesFolderType Apple Menu Folder 'amnu' kAppleMenuFolderType Startup Folder 'strt' kStartupFolderType Print Monitor Folder 'spoo' kSpoolFolderType Temporary folder 'temp' kTemporaryFolderType Desktop folder 'desk' kDesktopFolderType Single-user trash folder 'trsh' kTrashFolderType Shared trash folder 'empt' kSharedTrashFolderType In calls to FindFolder, you can use these three constants: CONST kOnSystemDisk = $8000; kCreateFolder = TRUE; kDontCreateFolder = FALSE; Call the FindFolder function to get a volume and directory ID for a special folder. The FindFolder function returns the volume reference number and directory ID of a specified special folder on a specified volume. You specify a volume reference number (or the constant kOnSystemDisk for the boot disk) in the vRefNum parameter. You specify the folder type in the folderType parameter, using one of the constants listed in Table 8-2. The createFolder parameter tells FindFolder whether or not to create a folder if it does not already exist. FindFolder puts the results in foundVRefNum and foundDirID. Result codes fnfErr -43 Type not found in 'fld# resource; Folder not found and createFolder flag false dupFNErr -48 File found instead of folder æKY Fonts.h æKL FMSwapFont FontMetrics getfnum GetFNum getfontname GetFontName InitFonts RealFont SetFontLock SetFractEnable SetFScaleDisable appleMark applFont AsscEntry athens cairo checkMark commandMark courier diamondMark FamRec fixedFont FMetricRec FMInput FMOutPtr FMOutput FontAssoc FontRec fontWid fxdFntH fxdFntHW fxdFntW geneva helvetica KernEntry KernPair KernTable london losAngeles mobile monaco NameTable newYork propFont prpFntH prpFntHW prpFntW sanFran StyleTable symbol systemFont times toronto venice WidEntry WidTable WidthTable æKY systemFont æFc Fonts.h æT #define æD #define systemFont 0 æC _______________________________________________________________________________ »FONT NUMBERS _______________________________________________________________________________ Note: The information on Font Numbers described in the following paragraphs was originally documented in Inside Macintosh, Volume I. The Font Manager includes the following font numbers for identifying system-defined fonts: CONST systemFont = 0; {system font} applFont = 1; {application font} newYork = 2; geneva = 3; monaco = 4; venice = 5; london = 6; athens = 7; sanFran = 8; toronto = 9; cairo = 11; losAngeles = 12; times = 20; helvetica = 21; courier = 22; symbol = 23; taliesin = 24; The system font is so called because it’s the font used by the system (for drawing menu titles and commands in menus, for example). The name of the system font is Chicago. The size of text drawn by the system in this font is fixed at 12 points (called the system font size). The application font is the font your application will use unless you specify otherwise. Unlike the system font, the application font isn’t a separate font, but is essentially a reference to another font—Geneva, by default. (The application font number is determined by a value that you can set in parameter RAM; see the Operating System Utilities chapter for more information.) Assembly-language note: You can get the application font number from the global variable ApFontID. æKY applFont æFc Fonts.h æT #define æD #define applFont 1 æC æKY newYork æFc Fonts.h æT #define æD #define newYork 2 æC æKY geneva æFc Fonts.h æT #define æD #define geneva 3 æC æKY monaco æFc Fonts.h æT #define æD #define monaco 4 æC æKY venice æFc Fonts.h æT #define æD #define venice 5 æC æKY london æFc Fonts.h æT #define æD #define london 6 æC æKY athens æFc Fonts.h æT #define æD #define athens 7 æC æKY sanFran æFc Fonts.h æT #define æD #define sanFran 8 æC æKY toronto æFc Fonts.h æT #define æD #define toronto 9 æC æKY cairo æFc Fonts.h æT #define æD #define cairo 11 æC æKY losAngeles æFc Fonts.h æT #define æD #define losAngeles 12 æC æKY times æFc Fonts.h æT #define æD #define times 20 æC æKY helvetica æFc Fonts.h æT #define æD #define helvetica 21 æC æKY courier æFc Fonts.h æT #define æD #define courier 22 æC æKY symbol æFc Fonts.h æT #define æD #define symbol 23 æC æKY mobile æFc Fonts.h æT #define æD #define mobile 24 æC æKY commandMark æFc Fonts.h æT #define æD #define commandMark 17 æC _______________________________________________________________________________ »CHARACTERS IN A FONT _______________________________________________________________________________ Note: The information on the Characters In A Font described in the following paragraphs was originally documented in Inside Macintosh, Volume I. A font can consist of up to 255 distinct characters; not all characters need to be defined in a single font. Figure 20 shows the standard printing characters on the Macintosh and their ASCII codes (for example, the ASCII code for “A” is 41 hexadecimal, or 65 decimal). Note: Codes $00 through $1F and code $7F are normally nonprinting characters (see the Toolbox Event Manager chapter for details). The special characters in the system font with codes $11 through $14 can’t normally be typed from the keyboard or keypad. The Font Manager defines constants for these characters: CONST commandMark = $11; {Command key symbol} checkMark = $12; {check mark} diamondMark = $13; {diamond symbol} appleMark = $14; {apple symbol} In addition to its maximum of 255 characters, every font contains a missing symbol that’s drawn in case of a request to draw a character that’s missing from the font. •••Refer to Figure 20.••• Figure 20–Font Characters æKY checkMark æFc Fonts.h æT #define æD #define checkMark 18 æC æKY diamondMark æFc Fonts.h æT #define æD #define diamondMark 19 æC æKY appleMark æFc Fonts.h æT #define æD #define appleMark 20 æC æKY propFont æFc Fonts.h æT #define æD #define propFont 36864 æC æKY prpFntH æFc Fonts.h æT #define æD #define prpFntH 36865 æC æKY prpFntW æFc Fonts.h æT #define æD #define prpFntW 36866 æC æKY prpFntHW æFc Fonts.h æT #define æD #define prpFntHW 36867 æC æKY fixedFont æFc Fonts.h æT #define æD #define fixedFont 45056 æC æKY fxdFntH æFc Fonts.h æT #define æD #define fxdFntH 45057 æC æKY fxdFntW æFc Fonts.h æT #define æD #define fxdFntW 45058 æC æKY fxdFntHW æFc Fonts.h æT #define æD #define fxdFntHW 45059 æC æKY fontWid æFc Fonts.h æT #define æD #define fontWid 44208 æC æKY FMInput æFc Fonts.h æT struct æD struct FMInput { short family; short size; Style face; Boolean needBits; short device; Point numer; Point denom; }; typedef struct FMInput FMInput; æC ______________________________________________________________________________ »COMMUNICATION BETWEEN QUICKDRAW AND THE FONT MANAGER _______________________________________________________________________________ This section describes the data structures that allow QuickDraw and the Font Manager to exchange information. It also discusses the communication that may occur between the Font Manager and the driver of the device on which the characters are being drawn or printed. You can skip this section if you want to change fonts, character style, and font sizes by calling QuickDraw and aren’t interested in the lower-level data structures and routines of the Font Manager. To understand this section fully, you’ll have to be familiar with device drivers and the Device Manager. Whenever you call a QuickDraw routine that does anything with text, QuickDraw requests information from the Font Manager about the characters. The Font Manager performs any necessary calculations and returns the requested information to QuickDraw. As illustrated in Figure 21, this information exchange occurs via two data structures, a font input record (type FMInput) and a font output record (type FMOutput). First, QuickDraw passes the Font Manager a font input record: TYPE FMInput = PACKED RECORD family: INTEGER; {font number} size: INTEGER; {font size} face: Style; {character style} needBits: BOOLEAN; {TRUE if drawing} device: INTEGER; {device-specific information} numer: Point; {numerators of scaling factors} denom: Point {denominators of scaling factors} END; The first three fields contain the font number, size, and character style that QuickDraw wants to use. The needBits field indicates whether the characters actually will be drawn or not. If the characters are being drawn, all of the information describing the font, including the bit image comprising the characters, will be read into memory. If the characters aren’t being drawn and there’s a resource consisting of only the character widths and general font information, that resource will be read instead. The high-order byte of the device field contains a device driver reference number. From the driver reference number, the Font Manager can determine the optimum stylistic variations on the font to produce the highest-quality printing or drawing available on a device (as explained below). The low-order byte of the device field is ignored by the Font Manager but may contain information used by the device driver. •••Refer to Figure 21.••• Figure 21–Communication About Fonts The numer and denom fields contain the scaling factors to be used; numer.v divided by denom.v gives the vertical scaling, and numer.h divided by denom.h gives the horizontal scaling. The Font Manager takes the font input record and asks the Resource Manager for the font. If the requested size isn’t available, the Font Manager scales another size to match (as described under “Font Scaling”). Then the Font Manager gets the font characterization table via the device field. If the high-order byte of the device field is 0, the Font Manager gets the screen’s font characterization table (which is stored in the Font Manager). If the high-order byte of the device field is nonzero, the Font Manager calls the status routine of the device driver having that reference number, and the status routine returns a font characterization table. The status routine may use the value of the low-order byte of the device field to determine the font characterization table it should return. Note: If you want to make your own calls to the device driver’s Status function, the reference number must be the driver reference number from the font input record’s device field, csCode must be 8, csParam must be a pointer to where the device driver should put the font characterization table, and csParam+4 must be an integer containing the value of the font input record’s device field. Figure 22 shows the structure of a font characterization table and, on the right, the values it contains for the Macintosh screen. •••Refer to Figure 22.••• Figure 22–Font Characterization Table The first two words of the font characterization table contain the approximate number of dots per inch on the device. These values are only used for scaling between devices; they don’t necessarily correspond to a device’s actual resolution. The remainder of the table consists of three-byte triplets providing information about the different stylistic variations. For all but the triplet defining the underline characteristics: • The first byte in the triplet indicates which byte beyond the bold field of the font output record (see below) is affected by the triplet. • The second byte contains the amount to be stored in the affected field. • The third byte indicates the amount by which the extra field of the font output record is to be incremented (starting from 0). The triplet defining the underline characteristics indicates the amount by which the font output record’s ulOffset, ulShadow, and ulThick fields (respectively) should be incremented. æKY FMOutput FMOutPtr æFc Fonts.h æT struct æD struct FMOutput { short errNum; Handle fontHandle; unsigned char boldPixels; unsigned char italicPixels; unsigned char ulOffset; unsigned char ulShadow; unsigned char ulThick; unsigned char shadowPixels; char extra; unsigned char ascent; unsigned char descent; unsigned char widMax; char leading; char unused; Point numer; Point denom; }; typedef struct FMOutput FMOutput; typedef FMOutput *FMOutPtr; æC Based on the information in the font characterization table, the Font Manager determines the optimum ascent, descent, and leading, so that the highest-quality printing or drawing available will be produced. It then stores this information in a font output record: TYPE FMOutput = PACKED RECORD errNum: INTEGER; {not used} fontHandle: Handle; {handle to font record} bold: Byte; {bold factor} italic: Byte; {italic factor} ulOffset: Byte; {underline offset} ulShadow: Byte; {underline shadow} ulThick: Byte; {underline thickness} shadow: Byte; {shadow factor} extra: SignedByte; {width of style} ascent: Byte; {ascent} descent: Byte; {descent} widMax: Byte; {maximum character width} leading: SignedByte; {leading} unused: Byte; {not used} numer: Point; {numerators of scaling factors} denom: Point {denominators of scaling factors} END; ErrNum is reserved for future use, and is set to 0. FontHandle is a handle to the font record of the font, as described in the next section. Bold, italic, ulOffset, ulShadow, ulThick, and shadow are all fields that modify the way stylistic variations are done; their values are taken from the font characterization table, and are used by QuickDraw. (You’ll need to experiment with these values if you want to determine exactly how they’re used.) Extra indicates the number of pixels that each character has been widened by stylistic variation. For example, using the screen values shown in Figure 22, the extra field for bold shadowed characters would be 3. Ascent, descent, widMax, and leading are the same as the fields of the FontInfo record returned by the QuickDraw procedure GetFontInfo. Numer and denom contain the scaling factors. Just before returning this record to QuickDraw, the Font Manager calls the device driver’s control routine to allow the driver to make any final modifications to the record. Finally, the font information is returned to QuickDraw via a pointer to the record, defined as follows: TYPE FMOutPtr = ^FMOutput; Note: If you want to make your own calls to the device driver’s Control function, the reference number must be the driver reference number from the font input record’s device field, csCode must be 8, csParam must be a pointer to the font output record, and csParam+4 must be the value of the font input record’s device field. æKY FontRec æFc Fonts.h æT struct æD struct FontRec { short fontType; /*font type*/ short firstChar; /*ASCII code of first character*/ short lastChar; /*ASCII code of last character*/ short widMax; /*maximum character width*/ short kernMax; /*negative of maximum character kern*/ short nDescent; /*negative of descent*/ short fRectWidth; /*width of font rectangle*/ short fRectHeight; /*height of font rectangle*/ short owTLoc; /*offset to offset/width table*/ short ascent; /*ascent*/ short descent; /*descent*/ short leading; /*leading*/ short rowWords; /*row width of bit image / 2 */ }; typedef struct FontRec FontRec; æC »Font Records The information describing a font is contained in a data structure called a font record, which contains the following: • the font type (fixed-width or proportional) • the ASCII code of the first character and the last character in the font • the maximum character width and maximum amount any character kerns • the font height, ascent, descent, and leading • the bit image of the font • a location table, which is an array of words specifying the location of each character image within the bit image • an offset/width table, which is an array of words specifying the character offset and character width for each character in the font For every character, the location table contains a word that specifies the bit offset to the location of that character’s image in the bit image. The entry for a character missing from the font contains the same value as the entry for the next character. The last word of the table contains the offset to one bit beyond the end of the bit image (that is, beyond the character image for the missing symbol). The image width of each character is determined from the location table by subtracting the bit offset to that character from the bit offset to the next character in the table. There’s also one word in the offset/width table for every character: The high-order byte specifies the character offset and the low order byte specifies the character width. Missing characters are flagged in this table by a word value of –1. The last word is also –1, indicating the end of the table. Note: The 64K ROM version of the Resource Manager limits the total space occupied by the bit image, location table, offset/width table, and character-width and image-height tables to 32K bytes. For this reason, the practical limit on the font size of a full font is about 40 points. Figure 9 illustrates a sample location table and offset/width table corresponding to the bit image in Figure 8 above. A font record is referred to by a handle that you can get by calling the FMSwapFont function or the Resource Manager function GetResource. The data type for a font record is as follows: TYPE FontRec = RECORD fontType: INTEGER; {font type} firstChar: INTEGER; {ASCII code of first character} lastChar: INTEGER; {ASCII code of last character} widMax: INTEGER; {maximum character width} kernMax: INTEGER; {negative of maximum character kern} nDescent: INTEGER; {negative of descent} fRectWidth: INTEGER; {width of font rectangle} fRectHeight: INTEGER; {height of font rectangle} owTLoc: INTEGER; {offset to offset/width table} ascent: INTEGER; {ascent} descent: INTEGER; {descent} leading: INTEGER; {leading} rowWords: INTEGER; {row width of bit image / 2} { bitImage: ARRAY[1..rowWords,1..fRectHeight] OF INTEGER; } {bit image} { locTable: ARRAY[firstChar..lastChar+2] OF INTEGER; } {location table} { owTable: ARRAY[firstChar..lastChar+2] OF INTEGER; } {offset/width table} END; Note: The variable-length arrays appear as comments because they’re not valid Pascal syntax; they’re used only as conceptual aids. •••Refer to Figure 9.••• Figure 9–Sample Location Table and Offset/Width Table The fontType field must contain one of the following predefined constants: CONST propFont = $9000; {proportional font} fixedFont = $B000; {fixed-width font} The values in the widMax, kernMax, nDescent, fRectWidth, fRectHeight, ascent, descent, and leading fields all specify a number of pixels. KernMax indicates the largest number of pixels any character kerns, that is, the distance from the character origin to the left edge of the font rectangle. It should always be 0 or negative, since the kerned pixels are to the left of the character origin. NDescent is the negative of the descent (the distance from the character origin to the bottom of the font rectangle). The owTLoc field contains a word offset from itself to the offset/width table; it’s equivalent to 4 + (rowWords * fRectHeight) + (lastChar–firstChar+3) + 1 Warning: Remember, the offset and row width in a font record are given in words, not bytes. Assembly-language note: The global variable ROMFont0 contains a handle to the font record for the system font. Every size of a font is stored as a separate resource. The resource type for a font is 'FONT'. The resource data for a font is simply a font record: Number of bytes Contents 2 bytes FontType field of font record 2 bytes FirstChar field of font record 2 bytes LastChar field of font record 2 bytes WidMax field of font record 2 bytes KernMax field of font record 2 bytes NDescent field of font record 2 bytes FRectWidth field of font record 2 bytes FRectHeight field of font record 2 bytes OWTLoc field of font record 2 bytes Ascent field of font record 2 bytes Descent field of font record 2 bytes Leading field of font record 2 bytes RowWords field of font record n bytes Bit image of font n = 2 * rowWords * fRectHeight m bytes Location table of font m = 2 * (lastChar–firstChar+3) m bytes Offset/width table of font m = 2 * (lastChar–firstChar+3) As shown in Figure 10, the resource ID of a font has the following format: Bits 0-6 are the font size, bits 7-14 are the font number, and bit 15 is 0. Thus the resource ID corresponding to a given font number and size is (128 * font number) + font size •••Refer to Technical Note #245:••• Since 0 is not a valid font size, the resource ID having 0 in the size field is used to provide only the name of the font: The name of the resource is the font name. For example, for a font named Griffin and numbered 200, the resource naming the font would have a resource ID of 25600 and the resource name 'Griffin'. Size 10 of that font would be stored in a resource numbered 25610. •••Refer to Figure 10.••• Figure 10–Resource ID for a Font The resource type 'FRSV' is reserved by the Font Manager; it identifies fonts used by the system. Fonts whose resource IDs are contained in a 'FRSV' resource 1 will not be removed from the system resource file by the Font/DA Mover. The format of a 'FRSV' resource is as follows: Number of bytes Contents 2 bytes Number of font resource IDs n * 2 bytes n font resource IDs æKY FMetricRec æFc Fonts.h æT struct æD struct FMetricRec { Fixed ascent; /*base line to top*/ Fixed descent; /*base line to bottom*/ Fixed leading; /*leading between lines*/ Fixed widMax; /*maximum character width*/ Handle wTabHandle; /*handle to font width table*/ }; typedef struct FMetricRec FMetricRec; æC æKY WidEntry æFc Fonts.h æT struct æD struct WidEntry { short widStyle; /*style entry applies to*/ }; typedef struct WidEntry WidEntry; æC æKY WidTable æFc Fonts.h æT struct æD struct WidTable { short numWidths; /*number of entries - 1*/ }; typedef struct WidTable WidTable; æC æKY AsscEntry æFc Fonts.h æT struct æD struct AsscEntry { short fontSize; short fontStyle; short fontID; /*font resource ID*/ }; typedef struct AsscEntry AsscEntry; æC æKY FontAssoc æFc Fonts.h æT struct æD struct FontAssoc { short numAssoc; /*number of entries - 1*/ }; typedef struct FontAssoc FontAssoc; æC æKY StyleTable æFc Fonts.h æT struct æD struct StyleTable { short fontClass; long offset; long reserved; char indexes[48]; }; typedef struct StyleTable StyleTable; æC æKY NameTable æFc Fonts.h æT struct æD struct NameTable { short stringCount; Str255 baseFontName; }; typedef struct NameTable NameTable; æC æKY KernPair æFc Fonts.h æT struct æD struct KernPair { char kernFirst; /*1st character of kerned pair*/ char kernSecond; /*2nd character of kerned pair*/ short kernWidth; /*kerning in 1pt fixed format*/ }; typedef struct KernPair KernPair; æC æKY KernEntry æFc Fonts.h æT struct æD struct KernEntry { short kernLength; /*length of this entry*/ short kernStyle; /*style the entry applies to*/ }; typedef struct KernEntry KernEntry; æC æKY KernTable æFc Fonts.h æT struct æD struct KernTable { short numKerns; /*number of kerning entries*/ }; typedef struct KernTable KernTable; æC æKY WidthTable æFc Fonts.h æT struct æD struct WidthTable { Fixed tabData[256]; /*character widths*/ Handle tabFont; /*font record used to build table*/ long sExtra; /*space extra used for table*/ long style; /*extra due to style*/ short fID; /*font family ID*/ short fSize; /*font size request*/ short face; /*style (face) request*/ short device; /*device requested*/ Point inNumer; /*scale factors requested*/ Point inDenom; /*scale factors requested*/ short aFID; /*actual font family ID for table*/ Handle fHand; /*family record used to build up table*/ Boolean usedFam; /*used fixed point family widths*/ unsigned char aFace; /*actual face produced*/ short vOutput; /*vertical scale output value*/ short hOutput; /*horizontal scale output value*/ short vFactor; /*vertical scale output value*/ short hFactor; /*horizontal scale output value*/ short aSize; /*actual size of actual font used*/ short tabSize; /*total size of table*/ }; typedef struct WidthTable WidthTable; æC »Global Width Tables Note: The extensions to the Font Manager described in the following paragraphs were originally documented in Inside Macintosh, Volume IV. As such, this information refers to the 128K ROMs and System file version 3.2 and later. The Font Manager communicates fractional character widths to QuickDraw via a global width table, a data structure allocated in the system heap. A handle to the global width table is returned by the FontMetrics procedure. The format of the global width table is follows: TYPE WidthTable = RECORD tabData: ARRAY[1..256] OF Fixed; { character widths} tabFont: Handle; {font record used to build table} sExtra: LONGINT; {space extra used for table} style: LONGINT; {extra due to style} fID: INTEGER; {font family ID} fSize: INTEGER; {font size request} face: INTEGER; {style (face) request} device: INTEGER; {device requested} inNumer: Point; {numerators of scaling factors} inDenom: Point; {denominators of scaling factors} aFID: INTEGER; {actual font family ID for table} fHand: handle; {family record used to build table} usedFam: BOOLEAN; {used fixed-point family widths} aFace: Byte; {actual face produced} vOutput: INTEGER; {vertical factor for expanding } { characters} hOutput: INTEGER; {horizontal factor for expanding } { characters} vFactor: INTEGER; {not used} hFactor: INTEGER; {horizontal factor for increasing } { character widths} aSize: INTEGER; {actual size of actual font used} tabSize: INTEGER {total size of table} END; TabData is an array containing a character width for each of the 255 possible characters in a font, plus one long word for the font’s missing symbol. The widths are stored in the standard 32-bit fixed-point format. If a character is missing, its entry contains the width of the missing symbol. (For efficiency, the Font Manager will store up to 12 recently used global width tables.) InNumer and inDenom contain the vertical and horizontal scaling factors copied from the font input record. Scaling is effected in two ways: by expanding characters of the chosen font and by artificially increasing the widths of the chosen font in the width table. HOutput and vOutput give the factors by which characters are to be expanded horizontally and vertically. HFactor is the factor by which the widths of the chosen font, after stylistic variations, have been increased. (VFactor is not used.) Thus, multiplying hOutput and vOutput by hFactor and vFactor gives the true font scaling; the product of hOutput and an entry in the width table is that character’s true scaled width. HOutput,vOutput, hFactor, and vFactor are all 16-bit fixed-point numbers, with an integer part in the high-order byte and a fractional part in the low-order byte. If font scaling has been enabled, hFactor and vFactor both have a value of 1. In any case, hOutput, vOutput, hFactor, and vFactor are adjusted so that the values of hFactor and vFactor lie between 1 and 2, including 1. Assembly-language note: A handle to the global width table is contained in the global variable WidthTabHandle. A pointer to the table is contained in the global variable WidthPtr; it’s reliable immediately after a call to FMSwapFont but, like all pointers, may become invalid after a call to the Memory Manager. The global variable WidthListHand is a handle to a list of handles to up to 12 recently-used width tables. You can scan this list, looking for width tables that match the family number, size, and style of the font you wish to measure. If you reach a width handle that’s equal to –1, that width table is invalid, and you must make an FMSwapFont call to get a valid one. When you reach a handle that’s zero, you’ve reached the end of the list. You should not use the global width table when special international interface software is being used to accommodate non-Roman alphabets. You can recognize such software by looking at the global variable IntlSpec; if it’s greater than 0, special international software is installed. If your application uses non-Roman alphabets, write to Developer Technical Support Apple Computer, Inc. 20525 Mariani Avenue, M/S 75-3T Cupertino, CA 95014 for the latest version of the International Utilities Package, which will be extended to handle non-Roman alphabets. æKY FamRec æFc Fonts.h æT struct æD struct FamRec { short ffFlags; /*flags for family*/ short ffFamID; /*family ID number*/ short ffFirstChar; /*ASCII code of 1st character*/ short ffLastChar; /*ASCII code of last character*/ short ffAscent; /*maximum ascent for 1pt font*/ short ffDescent; /*maximum descent for 1pt font*/ short ffLeading; /*maximum leading for 1pt font*/ short ffWidMax; /*maximum widMax for 1pt font*/ long ffWTabOff; /*offset to width table*/ long ffKernOff; /*offset to kerning table*/ long ffStylOff; /*offset to style mapping table*/ short ffProperty[9]; /*style property info*/ short ffIntl[2]; /*for international use*/ short ffVersion; /*version number*/ }; typedef struct FamRec FamRec; æC »Family Records Note: The extensions to the Font Manager described in the following paragraphs were originally documented in Inside Macintosh, Volume IV. As such, this information refers to the 128K ROMs and System file version 3.2 and later. Assembly-language note: The global variable LastFOND is a handle to the last family record used. You can read the contents of the family record by using this handle. You should not alter the contents of this record. The data type for a family record is as follows: TYPE FamRec = RECORD ffFlags: INTEGER; {flags for family} ffFamID: INTEGER; {family ID number} ffFirstChar: INTEGER; {ASCII code of the first character} ffLastChar: INTEGER; {ASCII code of the last character} ffAscent: INTEGER; {maximum ascent for 1-pt.font} ffDescent: INTEGER; {maximum descent for 1-pt.font} ffLeading: INTEGER; {maximum leading for 1-pt.font} ffWidMax: INTEGER; {maximum width for 1-pt.font} ffWTabOff: LONGINT; {offset to width table} ffKernOff: LONGINT; {offset to kerning table} ffStylOff: LONGINT; {offset to style-mapping table} ffProperty: ARRAY[1..9] OF INTEGER; {style property info} ffIntl: ARRAY[1..2] OF INTEGER; {reserved} ffVersion: INTEGER; {version number} { ffAssoc: FontAssoc;} {font association table} { ffWidthTab: WidTable;} {width table} { ffStyTab: StyleTable;}{style-mapping table} { ffKernTab: KernTable;} {kerning table} END; Note: The variable-length arrays appear as comments because they’re not valid Pascal syntax; they’re used only as conceptual aids. This version of the FamRec is accurate for Volume IV; the extensions to the FamRec made in Volume V are not included here. The ffFlags field defines general characteristics of the font family, as follows: Bit Meaning 0 Set if there’s an image-height table 1 Set if there’s a character-width table 2–11 Reserved (should be zero) 12 Set to ignore FractEnable when deciding whether to use fixed-point values for stylistic variations (see bit 13), clear to treat FractEnable as usual 13 Set to use integer extra width for stylistic variations, clear to compute fixed-point extra width from the family style-mapping table when FractEnable is TRUE 14 Set if family fractional-width table is not used, clear if table is used 15 Set for fixed-width font, clear for proportional font The values in the ffAscent, ffDescent, ffLeading, and ffWidMax describe the maximum dimensions of the family as they would be for a hypothetical one-point font to be scaled up. They use a special 16-bit fixed-point format with an integer part in the high-order 4 bits and a fractional part in the low-order 12 bits. The FontMetrics procedure calculates the true values by multiplying this number by the actual point size. The ffWTabOff, ffKernOff, and ffStylOff fields are offsets from the top of the record to the start of the width table, kerning table, and style-mapping table, respectively; if any of these fields is zero, the corresponding table does not exist. The ffProperty field is the family style-property table, shown in Figure 11. •••Refer to Figure 11.••• Figure 11–Family Style-Property Table Each entry is a 16-bit fixed-point number with a signed integer part in the high-order 4 bits and a fractional part in the low-order 12 bits. These numbers are used to calculate the amount of extra width for special stylistic variations; each of these values is multiplied by the point size of the font actually being used. If the font already exists for a given style, the value in its field is ignored. The ffAssoc field contains the font association table. This table, shown in Figure 12, is used to match a given font size and style combination with the resource ID of an actual font. •••Refer to Figure 12.••• Figure 12–Font Association Table Note: In order to reduce search time, the Font Manager requires that the entries be sorted according to the fontSize field, with the smallest sizes first. If multiple fonts from the same family, the plain (roman) fonts come first. The Font Manager is optimized to look first for 'NFNT' resources, then 'FONT' resources. Each entry in the font association table has the format shown in Figure 13. •••Refer to Figure 13.••• Figure 13–Font Association Table Entry The font association table is followed by the family character-width table. As shown in Figure 14, this table is actually a number of width tables (since a font family may include numerous styles). •••Refer to Figure 14.••• Figure 14–Family Character-Width Table Each character-width table is preceded by a style code; the low-order byte of this word specifies stylistic variations (see Figure 15). The widths in each table are for a hypothetical one-point font; the actual values for the characters are calculated by multiplying these widths by the font size. The widths in this table are stored in a 16-bit fixed-point format with an unsigned integer part in the high-order 4 bits and a fractional part in the low-order 12 bits. •••Refer to Figure 15.••• Figure 15–Style Codes The style-mapping table and its associated tables are used by the LaserWriter driver and are described in the Apple LaserWriter Reference. The kerning table, like the family character-width table, is actually a number of kerning tables (see Figure 16). •••Refer to Figure 16.••• Figure 16–Kerning Table Each kerning table is preceded by a style code; stored in the low-order byte of the word, this style information has the same format shown in Figure 15 above. The number of entries in the table follows the style word (see Figure 17). •••Refer to Figure 17.••• Figure 17–Structure of a Kerning Table The entries in each kerning table (shown in Figure 18) consist of a pair of characters followed by a kerning offset for a hypothetical one-point font. This value, represented by an integer part in the high-order 4 bits and a fractional part in the low-order 12 bits, is multiplied by the size of the font to obtain the actual offset. •••Refer to Figure 18.••• Figure 18–Kerning Table Entry Note: The extensions to the Font Manager described in the following paragraphs were originally documented in Inside Macintosh, Volume V. As such, this information refers to the Macintosh SE and Macintosh II ROMs and System file version 4.1 and later. For Macintosh II only, bits 8 and 9 of the font style word within each font association table specify the font depth; they must contain the same value as bits 2 and 3 of the fontType field of the font record. All other undefined bits remain 0. A font family is stored as a resource of type 'FOND', and with the Macintosh II, it’s format has been extended. The new format is the following (with extension fields indicated by asterisks): Number of bytes Contents 2 bytes FONDFlags field of family record 2 bytes FONDFamID field of family record 2 bytes FONDFirst field of family record 2 bytes FONDLast field of family record 2 bytes FONDAscent field of family record 2 bytes FONDDescent field of family record 2 bytes FONDLeading field of family record 2 bytes FONDWidMax field of family record 4 bytes FONDWTabOff of family record 4 bytes FONDKernOff of family record 4 bytes FONDStylOff of family record 24 bytes FONDProperty field of family record 4 bytes FONDIntl field of family record 2 bytes *Version number ($02) m bytes FONDAssoc field of family record (variable length) 2 bytes *Number of offsets minus 1 4 bytes *Offset to bounding box table n bytes *Bounding box table p bytes FONDWidTable field of family record (variable length) q bytes FONDStylTab field of family record (variable length) r bytes FONDKerntab field of family record (variable length) The bounding box table has an entry for each style available in the family. The table as a whole has this form: Number of bytes Contents 2 bytes Number of entries minus 1 10 bytes First entry 10 bytes Second entry . . . Each bounding box entry has this form, giving the bounding box position with respect to the origin of the characters: Number of bytes Contents 2 bytes Style word 2 bytes Lower left x coordinate 2 bytes Lower left y coordinate 2 bytes Upper right x coordinate 2 bytes Upper right y coordinate Note: The extensions to the Font Manager described in the following paragraphs were originally documented in Inside Macintosh, Volume IV. As such, this information refers to the 128K ROMs and System file version 3.2 and later. æKY InitFonts æFc Fonts.h æT Function æTN A8FE æD pascal void InitFonts(void) = 0xA8FE; æDT InitFonts()(void); æMM æRT 72 æRI I-222, P-31, 95, 101, 107, 112, 118, 174 æC InitFonts initializes the Font Manager. If the system font isn’t already in memory, InitFonts reads it into memory. Call this procedure once before all other Font Manager routines or any Toolbox routine that will call the Font Manager. æKY GetFontName æFc Fonts.h æT Function æTN A8FF æD pascal void GetFontName(short familyID,Str255 theName) = 0xA8FF; æDT GetFontName((short) familyID,(Str255) theName); æMM æRT 191 æRI I-223 æC Warning: Before returning, the routines in this section issue the Resource Manager call SetResLoad(TRUE). If your program previously called SetResLoad(FALSE) and you still want that to be in effect after calling one of these Font Manager routines, you’ll have to call SetResLoad(FALSE) again. PROCEDURE GetFontName (fontNum: INTEGER; VAR theName: Str255); Assembly-language note: The macro you invoke to call GetFontName from assembly language is named _GetFName. GetFontName returns in theName the name of the font having the font number fontNum. If there’s no such font, GetFontName returns the empty string. æKY GetFNum æFc Fonts.h æT Function æTN A900 æD pascal void GetFNum(const Str255 theName,short *familyID) = 0xA900; æDT GetFNum((const Str255) theName,(short *) familyID); æMM æRT 191 æRI I-223 æC Warning: Before returning, the routines in this section issue the Resource Manager call SetResLoad(TRUE). If your program previously called SetResLoad(FALSE) and you still want that to be in effect after calling one of these Font Manager routines, you’ll have to call SetResLoad(FALSE) again. GetFNum returns in theNum the font number for the font having the given fontName. If there’s no such font, GetFNum returns 0. æKY RealFont æFc Fonts.h æT Function æTN A902 æD pascal Boolean RealFont(short fontNum,short size) = 0xA902; æDT Boolean myVariable = RealFont((short) fontNum,(short) size); æMM æRI I-223 æC Warning: Before returning, the routines in this section issue the Resource Manager call SetResLoad(TRUE). If your program previously called SetResLoad(FALSE) and you still want that to be in effect after calling one of these Font Manager routines, you’ll have to call SetResLoad(FALSE) again. RealFont returns TRUE if the font having the font number fontNum is available in the given size in a resource file, or FALSE if the font has to be scaled to that size. Note: RealFont will always return FALSE if you pass applFont in fontNum. To find out if the application font is available in a particular size, call GetFontName and then GetFNum to get the actual font number for the application font, and then call RealFont with that number. æKY SetFontLock æFc Fonts.h æT Function æTN A903 æD pascal void SetFontLock(Boolean lockFlag) = 0xA903; æDT SetFontLock((Boolean) lockFlag); æMM æRI I-223 æC SetFontLock applies to the font in which text was most recently drawn. If lockFlag is TRUE, SetFontLock makes the font unpurgeable (reading it into memory if it isn’t already there). If lockFlag is FALSE, it releases the memory occupied by the font (by calling the Resource Manager procedure ReleaseResource). Since fonts are normally purgeable, this procedure is useful for making a font temporarily unpurgeable. æKY FMSwapFont æFc Fonts.h æT Function æTN A901 æD pascal FMOutPtr FMSwapFont(const FMInput *inRec) = 0xA901; æDT FMOutPtr myVariable = FMSwapFont((const FMInput *) inRec); æMM æRI I-223 æC The following low-level routine is called by QuickDraw and won’t normally be used by an application directly, but it may be of interest to advanced programmers who want to bypass the QuickDraw routines that deal with text. FUNCTION FMSwapFont (inRec: FMInput) : FMOutPtr; FMSwapFont returns a pointer to a font output record containing the size, style, and other information about an adapted version of the font requested in the given font input record. (Font input and output records are explained in the following section.) FMSwapFont is called by QuickDraw every time a QuickDraw routine that does anything with text is used. If you want to call FMSwapFont yourself, you must build a font input record and then use the pointer returned by FMSwapFont to access the resulting font output record. æKY SetFScaleDisable æFc Fonts.h æT Function æTN A834 æD pascal void SetFScaleDisable(Boolean fscaleDisable) = 0xA834; æDT SetFScaleDisable((Boolean) fscaleDisable); æRI IV-32 æC Note: The extensions to the Font Manager described in the following paragraphs were originally documented in Inside Macintosh, Volume IV. As such, this information refers to the 128K ROMs and System file version 3.2 and later. SetFScaleDisable lets you disable or enable font scaling. If fScaleDisable is TRUE, font scaling is disabled and the Font Manager returns an unscaled font with more space around the characters; if it’s FALSE, the Font Manager scales fonts. To ensure compatibility with existing applications, the Font Manager defaults to scaling fonts. Assembly-language note: All programmers should use the SetFScaleDisable procedure to disable and enable font scaling. In particular, setting the global variable FScaleDisable is insufficient. æKY FontMetrics æFc Fonts.h æT Function æTN A835 æD pascal void FontMetrics(const FMetricRec *theMetrics) = 0xA835; æDT FontMetrics((const FMetricRec *) theMetrics); æMM æRI IV-32 æC Note: The extensions to the Font Manager described in the following paragraphs were originally documented in Inside Macintosh, Volume IV. As such, this information refers to the 128K ROMs and System file version 3.2 and later. To improve the speed and readability of text display in your application, use the SetFractEnable and SetFScaleDisable procedures to enable fractional character widths and disable font scaling. Certain applications do not work properly when fractional character widths are used and font scaling is disabled, so these features are turned off by default. The FontMetrics function is much like QuickDraw’s GetFontInfo function except that it returns fixed-point values, letting you draw characters in more precise locations on the screen. If there’s a 'FOND' resource associated with the most recently drawn font, making the font resource purgeable or unpurgeable with the SetFontLock procedure will make the 'FOND' resource resource purgeable or unpurgeable as well. PROCEDURE FontMetrics (VAR theMetrics: FMetricRec); FontMetrics is similar to the QuickDraw procedure GetFontInfo except that it returns fixed-point values for greater accuracy in high-resolution printing. The FMetricRec data structure is defined as follows: TYPE FMetricRec = RECORD ascent: Fixed; {ascent} descent: Fixed; {descent} leading: Fixed; {leading} widMax: Fixed; {maximum character width} wTabHandle: Handle; {handle to global width table} END; Ascent, descent, leading, and widMax are identical in function to their counterparts in GetFontInfo. WTabHandle is a handle to the global width table (described below). æKY SetFractEnable æFc Fonts.h æT Function æD pascal void SetFractEnable(Boolean fractEnable); æDT SetFractEnable((Boolean) fractEnable); æRT 72 æRI V-180 æC Note: The extensions to the Font Manager described in the following paragraphs were originally documented in Inside Macintosh, Volume IV. As such, this information refers to the 128K ROMs and System file version 3.2 and later. SetFractEnable lets you enable or disable fractional character widths. If fractEnable is TRUE, fractional character widths are enabled; if it’s FALSE, the Font Manager uses integer widths. To ensure compatibility with existing applications, fractional character widths are disabled by default. SetFractEnable, which was not in the 128K ROM (but was available in the Pascal interfaces) has been added to both the Macintosh SE and Macintosh II ROMs. Assembly-language note: Assembly-language programmers should call SetFractEnable rather than change the value of the global variable FractEnable. æKY getfnum æFc Fonts.h æT Function æD void getfnum(char *theName,short *familyID); æDT getfnum((char *) theName,(short *) familyID); æMM æRT 191 æRI I-223 æC Warning: Before returning, the routines in this section issue the Resource Manager call SetResLoad(TRUE). If your program previously called SetResLoad(FALSE) and you still want that to be in effect after calling one of these Font Manager routines, you’ll have to call SetResLoad(FALSE) again. GetFNum returns in theNum the font number for the font having the given fontName. If there’s no such font, GetFNum returns 0. æKY getfontname æFc Fonts.h æT Function æD void getfontname(short familyID,char *theName); æDT getfontname((short) familyID,(char *) theName); æMM æRT 191 æRI I-223 æC Warning: Before returning, the routines in this section issue the Resource Manager call SetResLoad(TRUE). If your program previously called SetResLoad(FALSE) and you still want that to be in effect after calling one of these Font Manager routines, you’ll have to call SetResLoad(FALSE) again. PROCEDURE GetFontName (fontNum: INTEGER; VAR theName: Str255); Assembly-language note: The macro you invoke to call GetFontName from assembly language is named _GetFName. GetFontName returns in theName the name of the font having the font number fontNum. If there’s no such font, GetFontName returns the empty string. æKY GestaltEqu.h æKL Gestalt NewGestalt ReplaceGestalt gestalt32BitAddressing gestalt32BitCapable gestalt32BitQD gestalt32BitSysZone gestalt68000 gestalt68010 gestalt68020 gestalt68030 gestalt68030MMU gestalt68040 gestalt68040FPU gestalt68040MMU gestalt68851 gestalt68881 gestalt68882 gestalt8BitQD gestaltAddressingModeAttr gestaltAliasMgrAttr gestaltAliasMgrPresent gestaltAMU gestaltAppleEventsAttr gestaltAppleEventsPresent gestaltAppleTalkVersion gestaltAUXVersion gestaltClassic gestaltCTBVersion gestaltDBAccessMgrAttr gestaltDBAccessMgrPresent gestaltDupSelectorErr gestaltEditionMgrAttr gestaltEditionMgrPresent gestaltElmerISOKbd gestaltElmerKbd gestaltExtADBKbd gestaltExtendedTimeMgr gestaltExtISOADBKbd gestaltFolderMgrAttr gestaltFolderMgrPresent gestaltFontMgrAttr gestaltFPUType gestaltHardwareAttr gestaltHasASC gestaltHasParityCapability gestaltHasSCC gestaltHasSCSI gestaltHasVIA1 gestaltHasVIA2 gestaltHelpMgrAttr gestaltHelpMgrPresent gestaltIPCSupport gestaltKeyboardType gestaltLaunchCanReturn gestaltLaunchControl gestaltLaunchFullFileSpec gestaltLocationErr gestaltLogicalPageSize gestaltLogicalRAMSize gestaltLowMemorySize gestaltMac512KE gestaltMacAndPad gestaltMachineType gestaltMacII gestaltMacIIci gestaltMacIIcx gestaltMacIIfx gestaltMacIIx gestaltMacKbd gestaltMacPlus gestaltMacPlusKbd gestaltMacSE gestaltMacSE030 gestaltMacXL gestaltMiscAttr gestaltMMUType gestaltNoFPU gestaltNoMMU gestaltNotificationMgrAttr gestaltNotificationPresent gestaltOriginalQD gestaltOSAttr gestaltOutlineFonts gestaltParityAttr gestaltParityEnabled gestaltPartialRsrcs gestaltPhysicalRAMSize gestaltPMgrCPUIdle gestaltPMgrExists gestaltPMgrSCC gestaltPMgrSound gestaltPortable gestaltPowerMgrAttr gestaltPPCSupportsDontCare gestaltPPCSupportsIncomming gestaltPPCSupportsOutGoing gestaltPPCSupportsRealTime gestaltPPCSupportsStoreAndForward gestaltPPCToolboxAttr gestaltPPCToolboxPresent gestaltProcessorType gestaltPrtblADBKbd gestaltPrtblISOKbd gestaltQuickdrawVersion gestaltRealTempMemory gestaltResourceMgrAttr gestaltRevisedTimeMgr gestaltROMSize gestaltROMVersion gestaltScriptCount gestaltScriptMgrVersion gestaltScrollingThrottle gestaltSoundAttr gestaltStandardTimeMgr gestaltStdADBKbd gestaltStdISOADBKbd gestaltStereoCapability gestaltStereoMixing gestaltSysDebuggerSupport gestaltSystemVersion gestaltSysZoneGrowable gestaltTE1 gestaltTE2 gestaltTE3 gestaltTE4 gestaltTempMemSupport gestaltTempMemTracked gestaltTextEditVersion gestaltTimeMgrVersion gestaltUndefSelectorErr gestaltUnknownErr gestaltVersion gestaltVMAttr gestaltVMPresent æKY gestaltUnknownErr æFc GestaltEqu.h æT #define æD /* *********************** * Gestalt error codes *********************** */ #define gestaltUnknownErr -5550 /* value returned if Gestalt doesn't know the answer */ æC æKY gestaltUndefSelectorErr æFc GestaltEqu.h æT #define æD #define gestaltUndefSelectorErr -5551 /* undefined selector was passed to Gestalt */ æC æKY gestaltDupSelectorErr æFc GestaltEqu.h æT #define æD #define gestaltDupSelectorErr -5552 /* tried to add an entry that already existed */ æC æKY gestaltLocationErr æFc GestaltEqu.h æT #define æD #define gestaltLocationErr -5553 /* gestalt function ptr wasn't in sysheap */ æC æKY gestaltVersion æFc GestaltEqu.h æT #define æD /* ************************* * Environment Selectors ************************* */ #define gestaltVersion 'vers' /* gestalt version */ æC æKY gestaltAddressingModeAttr æFc GestaltEqu.h æT #define æD #define gestaltAddressingModeAttr 'addr' /* addressing mode attributes */ æC æKY gestalt32BitAddressing æFc GestaltEqu.h æT #define æD #define gestalt32BitAddressing 0 /* using 32-bit addressing mode */ æC æKY gestalt32BitSysZone æFc GestaltEqu.h æT #define æD #define gestalt32BitSysZone 1 /* 32-bit compatible system zone */ æC æKY gestalt32BitCapable æFc GestaltEqu.h æT #define æD #define gestalt32BitCapable 2 /* Machine is 32-bit capable */ æC æKY gestaltAliasMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltAliasMgrAttr 'alis' /* Alias Mgr Attributes */ æC æKY gestaltAliasMgrPresent æFc GestaltEqu.h æT #define æD #define gestaltAliasMgrPresent 0 /* True if the Alias Mgr is present */ æC æKY gestaltAppleTalkVersion æFc GestaltEqu.h æT #define æD #define gestaltAppleTalkVersion 'atlk' /* appletalk version */ æC æKY gestaltAUXVersion æFc GestaltEqu.h æT #define æD #define gestaltAUXVersion 'a/ux' /*a/ux version, if present */ æC æKY gestaltCTBVersion æFc GestaltEqu.h æT #define æD #define gestaltCTBVersion 'ctbv' /* CommToolbox version */ æC æKY gestaltDBAccessMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltDBAccessMgrAttr 'dbac' /* Database Access Mgr attributes */ æC æKY gestaltDBAccessMgrPresent æFc GestaltEqu.h æT #define æD #define gestaltDBAccessMgrPresent 0 /* True if Database Access Mgr present */ æC æKY gestaltEditionMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltEditionMgrAttr 'edtn' /* Edition Mgr attributes */ æC æKY gestaltEditionMgrPresent æFc GestaltEqu.h æT #define æD #define gestaltEditionMgrPresent 0 /* True if Edition Mgr present */ æC æKY gestaltAppleEventsAttr æFc GestaltEqu.h æT #define æD #define gestaltAppleEventsAttr 'evnt' /* Apple Events attributes */ æC æKY gestaltAppleEventsPresent æFc GestaltEqu.h æT #define æD #define gestaltAppleEventsPresent 0 /* True if Apple Events present */ æC æKY gestaltFolderMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltFolderMgrAttr 'fold' /* Folder Mgr attributes */ æC æKY gestaltFolderMgrPresent æFc GestaltEqu.h æT #define æD #define gestaltFolderMgrPresent 0 /* True if Folder Mgr present */ æC æKY gestaltFontMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltFontMgrAttr 'font' /* Font Mgr attributes */ æC æKY gestaltOutlineFonts æFc GestaltEqu.h æT #define æD #define gestaltOutlineFonts 0 /* True if Outline Fonts supported */ æC æKY gestaltFPUType æFc GestaltEqu.h æT #define æD #define gestaltFPUType 'fpu ' /* fpu type */ æC æKY gestaltNoFPU æFc GestaltEqu.h æT #define æD #define gestaltNoFPU 0 /* no FPU */ æC æKY gestalt68881 æFc GestaltEqu.h æT #define æD #define gestalt68881 1 /* 68881 FPU */ æC æKY gestalt68882 æFc GestaltEqu.h æT #define æD #define gestalt68882 2 /* 68882 FPU */ æC æKY gestalt68040FPU æFc GestaltEqu.h æT #define æD #define gestalt68040FPU 3 /* 68040 built-in FPU */ æC æKY gestaltHardwareAttr æFc GestaltEqu.h æT #define æD #define gestaltHardwareAttr 'hdwr' /* hardware attributes */ æC æKY gestaltHasVIA1 æFc GestaltEqu.h æT #define æD #define gestaltHasVIA1 0 /* VIA1 exists */ æC æKY gestaltHasVIA2 æFc GestaltEqu.h æT #define æD #define gestaltHasVIA2 1 /* VIA2 exists */ æC æKY gestaltHasASC æFc GestaltEqu.h æT #define æD #define gestaltHasASC 3 /* Apple Sound Chip exists */ æC æKY gestaltHasSCC æFc GestaltEqu.h æT #define æD #define gestaltHasSCC 4 /* SCC exists */ æC æKY gestaltHasSCSI æFc GestaltEqu.h æT #define æD #define gestaltHasSCSI 7 /* SCSI exists */ æC æKY gestaltHelpMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltHelpMgrAttr 'help' /* Help Mgr Attributes */ æC æKY gestaltHelpMgrPresent æFc GestaltEqu.h æT #define æD #define gestaltHelpMgrPresent 0 /* true if help mgr is present */ æC æKY gestaltKeyboardType æFc GestaltEqu.h æT #define æD #define gestaltKeyboardType 'kbd ' /* keyboard type */ æC æKY gestaltMacKbd æFc GestaltEqu.h æT #define æD #define gestaltMacKbd 1 æC æKY gestaltMacAndPad æFc GestaltEqu.h æT #define æD #define gestaltMacAndPad 2 æC æKY gestaltMacPlusKbd æFc GestaltEqu.h æT #define æD #define gestaltMacPlusKbd 3 æC æKY gestaltExtADBKbd æFc GestaltEqu.h æT #define æD #define gestaltExtADBKbd 4 æC æKY gestaltStdADBKbd æFc GestaltEqu.h æT #define æD #define gestaltStdADBKbd 5 æC æKY gestaltPrtblADBKbd æFc GestaltEqu.h æT #define æD #define gestaltPrtblADBKbd 6 æC æKY gestaltPrtblISOKbd æFc GestaltEqu.h æT #define æD #define gestaltPrtblISOKbd 7 æC æKY gestaltStdISOADBKbd æFc GestaltEqu.h æT #define æD #define gestaltStdISOADBKbd 8 æC æKY gestaltExtISOADBKbd æFc GestaltEqu.h æT #define æD #define gestaltExtISOADBKbd 9 æC æKY gestaltElmerKbd æFc GestaltEqu.h æT #define æD #define gestaltElmerKbd 10 æC æKY gestaltElmerISOKbd æFc GestaltEqu.h æT #define æD #define gestaltElmerISOKbd 11 æC æKY gestaltLowMemorySize æFc GestaltEqu.h æT #define æD #define gestaltLowMemorySize 'lmem' /* size of low memory area */ æC æKY gestaltLogicalRAMSize æFc GestaltEqu.h æT #define æD #define gestaltLogicalRAMSize 'lram' /* logical ram size */ æC æKY gestaltMiscAttr æFc GestaltEqu.h æT #define æD #define gestaltMiscAttr 'misc' /* miscellaneous attributes */ æC æKY gestaltScrollingThrottle æFc GestaltEqu.h æT #define æD #define gestaltScrollingThrottle 0 /* true if scrolling throttle on */ æC æKY gestaltMMUType æFc GestaltEqu.h æT #define æD #define gestaltMMUType 'mmu ' /* mmu type */ æC æKY gestaltNoMMU æFc GestaltEqu.h æT #define æD #define gestaltNoMMU 0 /* no MMU */ æC æKY gestaltAMU æFc GestaltEqu.h æT #define æD #define gestaltAMU 1 /* address management unit */ æC æKY gestalt68851 æFc GestaltEqu.h æT #define æD #define gestalt68851 2 /* 68851 PMMU */ æC æKY gestalt68030MMU æFc GestaltEqu.h æT #define æD #define gestalt68030MMU 3 /* 68030 built-in MMU */ æC æKY gestalt68040MMU æFc GestaltEqu.h æT #define æD #define gestalt68040MMU 4 /* 68040 built-in MMU */ æC æKY gestaltNotificationMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltNotificationMgrAttr 'nmgr' /* notification manager attributes */ æC æKY gestaltNotificationPresent æFc GestaltEqu.h æT #define æD #define gestaltNotificationPresent 0 /* notification manager exists */ æC æKY gestaltOSAttr æFc GestaltEqu.h æT #define æD #define gestaltOSAttr 'os ' /* o/s attributes */ æC æKY gestaltSysZoneGrowable æFc GestaltEqu.h æT #define æD #define gestaltSysZoneGrowable 0 /* system heap is growable */ æC æKY gestaltLaunchCanReturn æFc GestaltEqu.h æT #define æD #define gestaltLaunchCanReturn 1 /* can return from launch */ æC æKY gestaltLaunchFullFileSpec æFc GestaltEqu.h æT #define æD #define gestaltLaunchFullFileSpec 2 /* can launch from full file spec */ æC æKY gestaltLaunchControl æFc GestaltEqu.h æT #define æD #define gestaltLaunchControl 3 /* launch control support available */ æC æKY gestaltTempMemSupport æFc GestaltEqu.h æT #define æD #define gestaltTempMemSupport 4 /* temp memory support */ æC æKY gestaltRealTempMemory æFc GestaltEqu.h æT #define æD #define gestaltRealTempMemory 5 /* temp memory handles are real */ æC æKY gestaltTempMemTracked æFc GestaltEqu.h æT #define æD #define gestaltTempMemTracked 6 /* temporary memory handles are tracked */ æC æKY gestaltIPCSupport æFc GestaltEqu.h æT #define æD #define gestaltIPCSupport 7 /* IPC support is present */ æC æKY gestaltSysDebuggerSupport æFc GestaltEqu.h æT #define æD #define gestaltSysDebuggerSupport 8 /* system debugger support is present */ æC æKY gestaltLogicalPageSize æFc GestaltEqu.h æT #define æD #define gestaltLogicalPageSize 'pgsz' /* logical page size */ æC æKY gestaltPowerMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltPowerMgrAttr 'powr' /* power manager attributes */ æC æKY gestaltPMgrExists æFc GestaltEqu.h æT #define æD #define gestaltPMgrExists 0 æC æKY gestaltPMgrCPUIdle æFc GestaltEqu.h æT #define æD #define gestaltPMgrCPUIdle 1 æC æKY gestaltPMgrSCC æFc GestaltEqu.h æT #define æD #define gestaltPMgrSCC 2 æC æKY gestaltPMgrSound æFc GestaltEqu.h æT #define æD #define gestaltPMgrSound 3 æC æKY gestaltPPCToolboxAttr æFc GestaltEqu.h æT #define æD #define gestaltPPCToolboxAttr 'ppc ' /* PPC toolbox attributes */ æC æKY gestaltPPCToolboxPresent æFc GestaltEqu.h æT #define æD /* * PPC will return the combination of following bit fields. * e.g. gestaltPPCSupportsRealTime +gestaltPPCSupportsIncomming + gestaltPPCSupportsOutGoing * indicates PPC is cuurently is only supports real time delivery * and both icoming and outgoing network sessions are allowed. * By default local real time delivery is supported as long as PPCInit has been called. */ #define gestaltPPCToolboxPresent 0x0000 /* PPC Toolbox is present Requires PPCInit to be called */ æC æKY gestaltPPCSupportsRealTime æFc GestaltEqu.h æT #define æD #define gestaltPPCSupportsRealTime 0x1000 /* PPC Supports real-time delivery */ æC æKY gestaltPPCSupportsStoreAndForward æFc GestaltEqu.h æT #define æD #define gestaltPPCSupportsStoreAndForward 0x2000 /* PPC Store and Forward delivery */ æC æKY gestaltPPCSupportsDontCare æFc GestaltEqu.h æT #define æD #define gestaltPPCSupportsDontCare 0x4000 /* PPC Supports Specification of Don't care */ æC æKY gestaltPPCSupportsIncomming æFc GestaltEqu.h æT #define æD #define gestaltPPCSupportsIncomming 0x0001 /* PPC will deny incomming network requests */ æC æKY gestaltPPCSupportsOutGoing æFc GestaltEqu.h æT #define æD #define gestaltPPCSupportsOutGoing 0x0002 /* PPC will deny outgoing network requests */ æC æKY gestaltProcessorType æFc GestaltEqu.h æT #define æD #define gestaltProcessorType 'proc' /* processor type */ æC æKY gestalt68000 æFc GestaltEqu.h æT #define æD #define gestalt68000 1 æC æKY gestalt68010 æFc GestaltEqu.h æT #define æD #define gestalt68010 2 æC æKY gestalt68020 æFc GestaltEqu.h æT #define æD #define gestalt68020 3 æC æKY gestalt68030 æFc GestaltEqu.h æT #define æD #define gestalt68030 4 æC æKY gestalt68040 æFc GestaltEqu.h æT #define æD #define gestalt68040 5 æC æKY gestaltParityAttr æFc GestaltEqu.h æT #define æD #define gestaltParityAttr 'prty' /* parity attributes */ æC æKY gestaltHasParityCapability æFc GestaltEqu.h æT #define æD #define gestaltHasParityCapability 0 /* has ability to check parity */ æC æKY gestaltParityEnabled æFc GestaltEqu.h æT #define æD #define gestaltParityEnabled 1 /* parity checking enabled */ æC æKY gestaltQuickdrawVersion æFc GestaltEqu.h æT #define æD #define gestaltQuickdrawVersion 'qd ' /* quickdraw version */ æC æKY gestaltOriginalQD æFc GestaltEqu.h æT #define æD #define gestaltOriginalQD 0x000 /* original 1-bit QD <3.2> */ æC æKY gestalt8BitQD æFc GestaltEqu.h æT #define æD #define gestalt8BitQD 0x100 /* 8-bit color QD <3.2> */ æC æKY gestalt32BitQD æFc GestaltEqu.h æT #define æD #define gestalt32BitQD 0x200 /* 32-bit color QD <3.2> */ æC æKY gestaltPhysicalRAMSize æFc GestaltEqu.h æT #define æD #define gestaltPhysicalRAMSize 'ram ' /* physical RAM size */ æC æKY gestaltResourceMgrAttr æFc GestaltEqu.h æT #define æD #define gestaltResourceMgrAttr 'rsrc' /* Resource Mgr attributes */ æC æKY gestaltPartialRsrcs æFc GestaltEqu.h æT #define æD #define gestaltPartialRsrcs 0 /* True if partial resources exist */ æC æKY gestaltScriptMgrVersion æFc GestaltEqu.h æT #define æD #define gestaltScriptMgrVersion 'scri' /* Script Manager version number <08/05/89 pke> */ æC æKY gestaltScriptCount æFc GestaltEqu.h æT #define æD #define gestaltScriptCount 'scr#' /* number of active script systems <08/05/89 pke> */ æC æKY gestaltSoundAttr æFc GestaltEqu.h æT #define æD #define gestaltSoundAttr 'snd ' /* sound attributes */ æC æKY gestaltStereoCapability æFc GestaltEqu.h æT #define æD #define gestaltStereoCapability 0 /* sound hardware has stereo capability */ æC æKY gestaltStereoMixing æFc GestaltEqu.h æT #define æD #define gestaltStereoMixing 1 /* stereo mixing on external speaker */ æC æKY gestaltTextEditVersion æFc GestaltEqu.h æT #define æD #define gestaltTextEditVersion 'te ' /* TextEdit version number <08/05/89 pke> */ æC æKY gestaltTE1 æFc GestaltEqu.h æT #define æD #define gestaltTE1 1 /* TextEdit in MacIIci ROM <8Aug89smb> */ æC æKY gestaltTE2 æFc GestaltEqu.h æT #define æD #define gestaltTE2 2 /* TextEdit with 6.0.4 Script Systems on MacIIci (Script bug fixes for MacIIci) <8Aug89smb> */ æC æKY gestaltTE3 æFc GestaltEqu.h æT #define æD #define gestaltTE3 3 /* TextEdit with 6.0.4 Script Systems all but MacIIci <8Aug89smb> */ æC æKY gestaltTE4 æFc GestaltEqu.h æT #define æD /* **** Following is for System 7.0 Only **** */ #define gestaltTE4 4 /* TextEdit in System 7.0*/ æC æKY gestaltTimeMgrVersion æFc GestaltEqu.h æT #define æD #define gestaltTimeMgrVersion 'tmgr' /* time mgr version */ æC æKY gestaltStandardTimeMgr æFc GestaltEqu.h æT #define æD #define gestaltStandardTimeMgr 1 /* standard time mgr is present */ æC æKY gestaltRevisedTimeMgr æFc GestaltEqu.h æT #define æD #define gestaltRevisedTimeMgr 2 /* revised time mgr is present */ æC æKY gestaltExtendedTimeMgr æFc GestaltEqu.h æT #define æD #define gestaltExtendedTimeMgr 3 /* extended time mgr is present */ æC æKY gestaltVMAttr æFc GestaltEqu.h æT #define æD #define gestaltVMAttr 'vm ' /* virtual memory attributes */ æC æKY gestaltVMPresent æFc GestaltEqu.h æT #define æD #define gestaltVMPresent 0 /* true if virtual memory is present */ æC æKY gestaltMachineType æFc GestaltEqu.h æT #define æD /* ************************ * Info-only selectors *********************** */ #define gestaltMachineType 'mach' /* machine type */ æC æKY gestaltClassic æFc GestaltEqu.h æT #define æD #define gestaltClassic 1 æC æKY gestaltMacXL æFc GestaltEqu.h æT #define æD #define gestaltMacXL 2 æC æKY gestaltMac512KE æFc GestaltEqu.h æT #define æD #define gestaltMac512KE 3 æC æKY gestaltMacPlus æFc GestaltEqu.h æT #define æD #define gestaltMacPlus 4 æC æKY gestaltMacSE æFc GestaltEqu.h æT #define æD #define gestaltMacSE 5 æC æKY gestaltMacII æFc GestaltEqu.h æT #define æD #define gestaltMacII 6 æC æKY gestaltMacIIx æFc GestaltEqu.h æT #define æD #define gestaltMacIIx 7 æC æKY gestaltMacIIcx æFc GestaltEqu.h æT #define æD #define gestaltMacIIcx 8 æC æKY gestaltMacSE030 æFc GestaltEqu.h æT #define æD #define gestaltMacSE030 9 æC æKY gestaltPortable æFc GestaltEqu.h æT #define æD #define gestaltPortable 10 æC æKY gestaltMacIIci æFc GestaltEqu.h æT #define æD #define gestaltMacIIci 11 æC æKY gestaltMacIIfx æFc GestaltEqu.h æT #define æD #define gestaltMacIIfx 13 æC æKY gestaltROMSize æFc GestaltEqu.h æT #define æD #define gestaltROMSize 'rom ' /* rom size */ æC æKY gestaltROMVersion æFc GestaltEqu.h æT #define æD #define gestaltROMVersion 'romv' /* rom version */ æC æKY gestaltSystemVersion æFc GestaltEqu.h æT #define æD #define gestaltSystemVersion 'sysv' /* system version*/ æC æKY Gestalt æFc GestaltEqu.h æT Function æD pascal OSErr Gestalt(OSType selector,long *response); æDT OSErr myVariable = Gestalt((OSType) selector,(long *) response); æC Use the Gestalt function to obtain information about the operating environment. The information you need is indicated by the selector parameter, which Gestalt must already recognize. Trap macro _Gestalt On entry D0: selector code On exit A0: response D0: result code Upon successful completion of the function, the response parameter contains the information requested. Note that Gestalt returns the results from all function selectors in a long integer, occupying 4 bytes. In some cases, not all 4 bytes are needed to hold the returned information, in which case Gestalt places the information in the low-order bytes of the response parameter. Result codes noErr 0 No error gestaltUnknownErr –5550 Could not obtain the response gestaltUndefSelectorErr –5551 Undefined selector æKY NewGestalt æFc GestaltEqu.h æT Function æD pascal OSErr NewGestalt(OSType selector,ProcPtr gestaltFunction); æDT OSErr myVariable = NewGestalt((OSType) selector,(ProcPtr) gestaltFunction); æC Use the NewGestalt function to add selector codes to those already recognized by Gestalt. Trap macro _NewGestalt On entry A0: address of new selector function D0: selector code On exit D0: result code NewGestalt takes as parameters the selector to be registered and the function that Gestalt calls when it receives this selector. The interface for the selectorFunction function is defined in “Specifying Gestalt Selector Functions” earlier in this chapter. Result codes noErr 0 No error memFullErr –108 Ran out of memory gestaltDupSelectorErr –5552 Selector already exists gestaltLocationErr –5553 Function not in system heap æKY ReplaceGestalt æFc GestaltEqu.h æT Function æD pascal OSErr ReplaceGestalt(OSType selector,ProcPtr gestaltFunction,ProcPtr *oldGestaltFunction); æDT OSErr myVariable = ReplaceGestalt((OSType) selector,(ProcPtr) gestaltFunction,(ProcPtr *) oldGestaltFunction); æC The ReplaceGestalt function allows an application to replace the function that is currently associated with a selector. Trap macro _ReplaceGestalt On entry A0: address of new selector function D0: selector code On exit A0: address of old selector function D0: result code The interface for the selectorFunction function is defined in “Specifying Gestalt Selector Functions” earlier in this chapter. The new function must reside in the system heap and may want to call the function previously associated with the named selector. It may do so by using the address returned in the parameter oldGestaltFunction. If ReplaceGestalt returns an error of any type, then the value of oldGestaltFunction is undefined. Result codes noErr 0 No error gestaltUndefSelectorErr –5551 Undefined selector gestaltLocationErr –5553 Function not in system heap æKY Globals æKL ABusDCE ABusVars ACount ADBBase ANumber ASCBase AlarmState ApFontID AppParmHandle ApplLimit ApplScratch ApplZone BootDrive BufPtr BufTgDate BufTgFBkNum BufTgFFlg BufTgFNum BusErrVct CPUFlag CQDGlobals CaretTime ChunkyDepth ColLines CrsrAddr CrsrBase CrsrBusy CrsrCouple CrsrDevice CrsrNew CrsrObscure CrsrPin CrsrPtr CrsrRect CrsrRow CrsrSave CrsrScale CrsrState CrsrThresh CrsrVis CurActivate CurApName CurApRefNum CurDeactive CurDirStore CurJTOffset CurMap CurPageOption CurPitch CurStackBase CurrentA5 DABeeper DAStrings DSAlertRect DSAlertTab DSCtrAdj DSDrawProc DSErrCode DSWndUpdate DTQFlags DTQueue DTskQHdr DTskQTail DefVCBPtr DefltStack DeskHook DeskPattern DeviceList DlgFont DoubleTime DragHook DragPattern DrvQHdr DskErr DskVerify EjectNotify EndSRTPtr EventQueue EvtBufCnt ExpandMem ExtStsDT FCBSPtr FSQHdr FScaleDisable FinderName GZMoveHnd GZRootHnd GZRootPtr GetParam GhostWindow GrayRgn HeapEnd HiHeapMark HiKeyLast HiliteMode HiliteRGB HpChk IAZNotify IWM IconTLAddr IntFlag IntlSpec JAllocCrsr JCrsrTask JDTInstall JFetch JGNEFilter JIODone JKybdTask JOpcodeProc JSetCCrsr JStash JSwapMMU JVBLTask JournalFlag JournalRef KbdLast KbdType KbdVars Key1Trans Key2Trans KeyLast KeyMVars KeyMapLM KeyRepThresh KeyRepTime KeyThresh KeyTime KeypadMap LastTxGDevice LaunchFlag Lo3Bytes LoadTrap LoaderPBlock Lvl1DT Lvl2DT MBState MBTicks MBarEnable MBarHeight MBarHook MMDefFlags MMU32bit MMUFlags MMUFluff MMUTbl MMUTblSize MMUType MTemp MainDevice MaskBC MaskHandle MaskPtr MemErr MemTop MenuFlash MenuHook MenuList MickeyBytes MinStack MinusOne MmInOK MonkeyLives Mouse MouseMask MouseOffset NMIFlag NewCrsrJTbl OldContent OldStructure OneOne PCDeskPat PWMBuf2 PaintWhite PortAUse PortBUse PortList PrintErr QDColors QDErrLM QDExist RAMBase RGBBlack RGBWhite ROM85 ROMBase ROMFont0 ROMMapHndl RawMouse ResErr ResErrProc ResLoad ResReadOnly RestProc ResumeProc RndSeed RomMapInsert RowBits SCCASts SCCBSts SCCRd SCCWr SCSIBase SCSIDMA SCSIGlobals SCSIHsk SCSIPoll SDMJmpTblPtr SEVarBase SEvtEnb SFSaveDisk SInfoPtr SInitFlags SMGlobals SPATalkA SPATalkB SPAlarm SPClikCaret SPConfig SPFont SPKbd SPMisc1 SPMisc2 SPPortA SPPortB SPPrint SPValid SPVolCtl SRsrcTblPtr SaveSegHandle SaveUpdate SaveVisRgn ScrDmpEnb ScrDmpType ScrHRes ScrVRes ScrapCount ScrapEnd ScrapHandle ScrapInfo ScrapName ScrapSize ScrapState ScrapTag ScrapVars Scratch20 Scratch8 ScreenBytes ScreenRow ScrnBase ScrnVBLPtr SdVolume SdmBusErr SegHiEnable SerialVars SlotPrTbl SlotQDT SlotTICKS SlotVBLQ SoundActive SoundBase SoundDCE SoundLevel SoundPtr SoundVBL SrcDevice StkLowPt SwitcherTPtr SysEvtBuf SysEvtMask SysMap SysMapHndl SysParam SysResName SysVersion SysZone TEDoText TERecal TEScrpHandle TEScrpLength TESysJust TEWdBreak TableSeed TagData TheCrsr TheGDevice TheMenu TheZone Ticks Time TimeDBRA TimeLM TimeSCCDB TimeSCSIDB TmpResLoad ToExtFS ToolScratch TopMapHndl UTableBase UnitNtryCnt VBLQueue VCBQHdr VIA VIA2DT VertRRate VidMode VidType VideoInfoOK WMgrCPort WMgrPort WWExist WarmStart WindowList WordRedraw æKY ACount æFc Globals æD ACount 0xA9A [GLOBAL VAR] Stage number (0 through 3) of last alert (word) æKY ANumber æFc Globals æD ANumber 0xA98 [GLOBAL VAR] Resource ID of last alert (word) æKY ApFontID æFc Globals æD ApFontID 0x984 [GLOBAL VAR] Font number of application font (word) æKY ApplScratch æFc Globals æD ApplScratch 0xA78 [GLOBAL VAR] 12-byte scratch area reserved for use by applications æKY AppParmHandle æFc Globals æD AppParmHandle 0xAEC [GLOBAL VAR] Handle to Finder information æKY DABeeper æFc Globals æD DABeeper 0xA9C [GLOBAL VAR] Address of current sound procedure æKY DAStrings æFc Globals æD DAStrings 0xAA0 [GLOBAL VAR] Handles to ParamText strings (16 bytes) æKY DefVCBPtr æFc Globals æD DefVCBPtr 0x352 [GLOBAL VAR] Pointer to default volume control block æKY DlgFont æFc Globals æD DlgFont 0xAFA [GLOBAL VAR] Font number for dialogs and alerts (word) æKY DragPattern æFc Globals æD DragPattern 0xA34 [GLOBAL VAR] Pattern of dragged region's outline (8 bytes) æKY FCBSPtr æFc Globals æD FCBSPtr 0x34E [GLOBAL VAR] Pointer to file-control-block buffer æKY FinderName æFc Globals æD FinderName 0x2E0 [GLOBAL VAR] Name of the Finder (length byte followed by up to 15 characters) æKY FScaleDisable æFc Globals æC FScaleDisable 0xA63 [GLOBAL VAR] Nonzero to disable font scaling (byte) æKY FSQHdr æFc Globals æD FSQHdr 0x360 [GLOBAL VAR] File I/O queue header (10 bytes) æKY MBarEnable æFc Globals æD MBarEnable 0xA20 [GLOBAL VAR] Unique menu ID for active desk accessory, when menu bar belongs to the accessory (word) æKY MBarHook æFc Globals æD MBarHook 0xA2C [GLOBAL VAR] Address of routine called by MenuSelect before menu is drawn æKY MenuFlash æFc Globals æD MenuFlash 0xA24 [GLOBAL VAR] Count for duration of menu item blinking (word) æKY MenuHook æFc Globals æD MenuHook 0xA30 [GLOBAL VAR] Address of routine called during MenuSelect æKY MenuList æFc Globals æD MenuList 0xA1C [GLOBAL VAR] Handle to current menu list æKY OldContent æFc Globals æD OldContent 0x9EA [GLOBAL VAR] Handle to saved content region æKY OldStructure æFc Globals æD OldStructure 0x9E6 [GLOBAL VAR] Handle to saved structure region æKY PrintErr æFc Globals æD PrintErr 0x944 [GLOBAL VAR] Result code from last Printing Manager routine (word) æKY ROMFont0 æFc Globals æD ROMFont0 0x980 [GLOBAL VAR] Handle to font record for system font æKY SaveUpdate æFc Globals æD SaveUpdate 0x9DA [GLOBAL VAR] Flag for whether to generate update events (word) æKY SaveVisRgn æFc Globals æD SaveVisRgn 0x9F2 [GLOBAL VAR] Handle to saved visRgn æKY TheMenu æFc Globals æD TheMenu 0xA26 [GLOBAL VAR] Menu ID of currently highlighted menu (word) æKY ToExtFS æFc Globals æD ToExtFS 0x3F2 [GLOBAL VAR] Pointer to external file system æKY ToolScratch æFc Globals æD ToolScratch 0x9CE [GLOBAL VAR] 8-byte scratch area æKY VCBQHdr æFc Globals æD VCBQHdr 0x356 [GLOBAL VAR] Volume-control-block queue header (10 bytes) æKY Graf3D.h æKL Clip3D GetPort3D Identity InitGrf3d Line2D Line3D LineTo2D LineTo3D LookAt Move2D Move3D MoveTo2D MoveTo3D Open3DPort Pitch Roll Scale SetPort3D SetPt2D SetPt3D Skew Transform Translate ViewAngle ViewPort Yaw Point2D Point3D Port3D Port3DHandle Port3DPtr radConst XfMatrix æKY radConst æFc Graf3D.h æT #define æD #define radConst 3754936 æC æKY XfMatrix æFc Graf3D.h æT typedef æD typedef Fixed XfMatrix[4][4]; æC æKY Point3D æFc Graf3D.h æT struct æD struct Point3D { Fixed x; Fixed y; Fixed z; }; typedef struct Point3D Point3D; æC æKY Point2D æFc Graf3D.h æT struct æD struct Point2D { Fixed x; Fixed y; }; typedef struct Point2D Point2D; æC æKY Port3D Port3DPtr Port3DHandle æFc Graf3D.h æT struct æD struct Port3D { GrafPtr grPort; Rect viewRect; Fixed xLeft; Fixed yTop; Fixed xRight; Fixed yBottom; Point3D pen; Point3D penPrime; Point3D eye; Fixed hSize; Fixed vSize; Fixed hCenter; Fixed vCenter; Fixed xCotan; Fixed yCotan; char filler; char ident; XfMatrix xForm; }; typedef struct Port3D Port3D; typedef Port3D *Port3DPtr, **Port3DHandle; æC æKY InitGrf3d æFc Graf3D.h æT Function æD pascal void InitGrf3d(Port3DHandle port); æDT InitGrf3d((Port3DHandle) port); æC æKY Open3DPort æFc Graf3D.h æT Function æD pascal void Open3DPort(Port3DPtr port); æDT Open3DPort((Port3DPtr) port); æC æKY SetPort3D æFc Graf3D.h æT Function æD pascal void SetPort3D(Port3DPtr port); æDT SetPort3D((Port3DPtr) port); æC SetPort sets the grafPort indicated by gp to be the current port. The global pointer thePort always points to the current port. All QuickDraw drawing routines affect the bitMap thePort^.portBits and use the local coordinate system of thePort^. Note that OpenPort and InitPort do a SetPort to the given port. Warning: Never do a SetPort to a port that has not been opened with OpenPort. Each port possesses its own pen and text characteristics which remain unchanged when the port is not selected as the current port. æKY GetPort3D æFc Graf3D.h æT Function æD pascal void GetPort3D(Port3DPtr *port); æDT GetPort3D((Port3DPtr *) port); æC GetPort returns a pointer to the current grafPort. If you have a program that draws into more than one grafPort, it's extremely useful to have each procedure save the current grafPort (with GetPort), set its own grafPort, do drawing or calculations, and then restore the previous grafPort (with SetPort). The pointer to the current grafPort is also available through the global pointer thePort, but you may prefer to use GetPort for better readability of your program text. For example, a procedure could do a GetPort (savePort) before setting its own grafPort and a SetPort (savePort) afterwards to restore the previous port. æKY MoveTo2D æFc Graf3D.h æT Function æD pascal void MoveTo2D(Fixed x,Fixed y); æDT MoveTo2D((Fixed) x,(Fixed) y); æC MoveTo moves the pen to location (h,v) in the local coordinates of the current grafPort. No drawing is performed. æKY MoveTo3D æFc Graf3D.h æT Function æD pascal void MoveTo3D(Fixed x,Fixed y,Fixed z); æDT MoveTo3D((Fixed) x,(Fixed) y,(Fixed) z); æC æKY LineTo2D æFc Graf3D.h æT Function æD pascal void LineTo2D(Fixed x,Fixed y); æDT LineTo2D((Fixed) x,(Fixed) y); æC This procedure draws a line to the location that is a distance of dh horizontally and dv vertically from the current pen location; it calls LineTo(h+dh,v+dv), where (h,v) is the current location. The positive directions are to the right and down. The pen location becomes the coordinates of the end of the line after the line is drawn. See the general discussion of drawing. If a region or polygon is open and being formed, its outline is infinitely thin and is not affected by the pnSize, pnMode, or pnPat. (See OpenRgn and OpenPoly.) æKY Move2D æFc Graf3D.h æT Function æD pascal void Move2D(Fixed dx,Fixed dy); æDT Move2D((Fixed) dx,(Fixed) dy); æC æKY Move3D æFc Graf3D.h æT Function æD pascal void Move3D(Fixed dx,Fixed dy,Fixed dz); æDT Move3D((Fixed) dx,(Fixed) dy,(Fixed) dz); æC æKY Line2D æFc Graf3D.h æT Function æD pascal void Line2D(Fixed dx,Fixed dy); æDT Line2D((Fixed) dx,(Fixed) dy); æC æKY Line3D æFc Graf3D.h æT Function æD pascal void Line3D(Fixed dx,Fixed dy,Fixed dz); æDT Line3D((Fixed) dx,(Fixed) dy,(Fixed) dz); æC æKY ViewPort æFc Graf3D.h æT Function æD pascal void ViewPort(const Rect *r); æDT ViewPort((const Rect *) r); æC æKY LookAt æFc Graf3D.h æT Function æD pascal void LookAt(Fixed left,Fixed top,Fixed right,Fixed bottom); æDT LookAt((Fixed) left,(Fixed) top,(Fixed) right,(Fixed) bottom); æC æKY ViewAngle æFc Graf3D.h æT Function æD pascal void ViewAngle(Fixed angle); æDT ViewAngle((Fixed) angle); æC æKY Identity æFc Graf3D.h æT Function æD pascal void Identity(void); æDT Identity()(void); æC æKY Scale æFc Graf3D.h æT Function æD pascal void Scale(Fixed xFactor,Fixed yFactor,Fixed zFactor); æDT Scale((Fixed) xFactor,(Fixed) yFactor,(Fixed) zFactor); æC æKY Translate æFc Graf3D.h æT Function æD pascal void Translate(Fixed dx,Fixed dy,Fixed dz); æDT Translate((Fixed) dx,(Fixed) dy,(Fixed) dz); æC æKY Pitch æFc Graf3D.h æT Function æD pascal void Pitch(Fixed xAngle); æDT Pitch((Fixed) xAngle); æC æKY Yaw æFc Graf3D.h æT Function æD pascal void Yaw(Fixed yAngle); æDT Yaw((Fixed) yAngle); æC æKY Roll æFc Graf3D.h æT Function æD pascal void Roll(Fixed zAngle); æDT Roll((Fixed) zAngle); æC æKY Skew æFc Graf3D.h æT Function æD pascal void Skew(Fixed zAngle); æDT Skew((Fixed) zAngle); æC æKY Transform æFc Graf3D.h æT Function æD pascal void Transform(const Point3D *src,Point3D *dst); æDT Transform((const Point3D *) src,(Point3D *) dst); æC æKY Clip3D æFc Graf3D.h æT Function æD pascal short Clip3D(const Point3D *src1,const Point3D *src2,Point *dst1, Point *dst2); æDT short myVariable = Clip3D((const Point3D *) src1,(const Point3D *) src2,(Point *) dst1,( Point) * dst2); æC æKY SetPt3D æFc Graf3D.h æT Function æD pascal void SetPt3D(Point3D *pt3D,Fixed x,Fixed y,Fixed z); æDT SetPt3D((Point3D *) pt3D,(Fixed) x,(Fixed) y,(Fixed) z); æC SetPt assigns two integer coordinates to a variable of type Point. æKY SetPt2D æFc Graf3D.h æT Function æD pascal void SetPt2D(Point2D *pt2D,Fixed x,Fixed y); æDT SetPt2D((Point2D *) pt2D,(Fixed) x,(Fixed) y); æC æKY LineTo3D æFc Graf3D.h æT Function æD pascal void LineTo3D(Fixed x,Fixed y,Fixed z); æDT LineTo3D((Fixed) x,(Fixed) y,(Fixed) z); æC æKY HyperXCmd.h æKL BoolToStr EvalExpr ExtToStr GetFieldByID GetFieldByName GetFieldByNum GetGlobal LongToStr NumToHex NumToStr PasToZero ReturnToPas ScanToReturn ScanToZero SendCardMessage SendHCMessage SetFieldByID SetFieldByName SetFieldByNum SetGlobal StringEqual StringLength StringMatch StrToBool StrToExt StrToLong StrToNum ZeroBytes ZeroToPas XCmdBlock XCmdPtr xreqBoolToStr xreqEvalExpr xreqExtToStr xreqGetFieldByID xreqGetFieldByName xreqGetFieldByNum xreqGetGlobal xreqLongToStr xreqNumToHex xreqNumToStr xreqPasToZero xreqReturnToPas xreqScanToReturn xreqScanToZero xreqSendCardMessage xreqSendHCMessage xreqSetFieldByID xreqSetFieldByName xreqSetFieldByNum xreqSetGlobal xreqStringEqual xreqStringLength xreqStringMatch xreqStrToBool xreqStrToExt xreqStrToLong xreqStrToNum xreqZeroBytes xreqZeroToPas xresFail xresNotImp xresSucc æKY xresSucc æFc HyperXCmd.h æT #define æD /* result codes */ #define xresSucc 0 æC æKY xresFail æFc HyperXCmd.h æT #define æD #define xresFail 1 æC æKY xresNotImp æFc HyperXCmd.h æT #define æD #define xresNotImp 2 æC æKY xreqSendCardMessage æFc HyperXCmd.h æT #define æD /* request codes */ #define xreqSendCardMessage 1 æC æKY xreqEvalExpr æFc HyperXCmd.h æT #define æD #define xreqEvalExpr 2 æC æKY xreqStringLength æFc HyperXCmd.h æT #define æD #define xreqStringLength 3 æC æKY xreqStringMatch æFc HyperXCmd.h æT #define æD #define xreqStringMatch 4 æC æKY xreqSendHCMessage æFc HyperXCmd.h æT #define æD #define xreqSendHCMessage 5 æC æKY xreqZeroBytes æFc HyperXCmd.h æT #define æD #define xreqZeroBytes 6 æC æKY xreqPasToZero æFc HyperXCmd.h æT #define æD #define xreqPasToZero 7 æC æKY xreqZeroToPas æFc HyperXCmd.h æT #define æD #define xreqZeroToPas 8 æC æKY xreqStrToLong æFc HyperXCmd.h æT #define æD #define xreqStrToLong 9 æC æKY xreqStrToNum æFc HyperXCmd.h æT #define æD #define xreqStrToNum 10 æC æKY xreqStrToBool æFc HyperXCmd.h æT #define æD #define xreqStrToBool 11 æC æKY xreqStrToExt æFc HyperXCmd.h æT #define æD #define xreqStrToExt 12 æC æKY xreqLongToStr æFc HyperXCmd.h æT #define æD #define xreqLongToStr 13 æC æKY xreqNumToStr æFc HyperXCmd.h æT #define æD #define xreqNumToStr 14 æC æKY xreqNumToHex æFc HyperXCmd.h æT #define æD #define xreqNumToHex 15 æC æKY xreqBoolToStr æFc HyperXCmd.h æT #define æD #define xreqBoolToStr 16 æC æKY xreqExtToStr æFc HyperXCmd.h æT #define æD #define xreqExtToStr 17 æC æKY xreqGetGlobal æFc HyperXCmd.h æT #define æD #define xreqGetGlobal 18 æC æKY xreqSetGlobal æFc HyperXCmd.h æT #define æD #define xreqSetGlobal 19 æC æKY xreqGetFieldByName æFc HyperXCmd.h æT #define æD #define xreqGetFieldByName 20 æC æKY xreqGetFieldByNum æFc HyperXCmd.h æT #define æD #define xreqGetFieldByNum 21 æC æKY xreqGetFieldByID æFc HyperXCmd.h æT #define æD #define xreqGetFieldByID 22 æC æKY xreqSetFieldByName æFc HyperXCmd.h æT #define æD #define xreqSetFieldByName 23 æC æKY xreqSetFieldByNum æFc HyperXCmd.h æT #define æD #define xreqSetFieldByNum 24 æC æKY xreqSetFieldByID æFc HyperXCmd.h æT #define æD #define xreqSetFieldByID 25 æC æKY xreqStringEqual æFc HyperXCmd.h æT #define æD #define xreqStringEqual 26 æC æKY xreqReturnToPas æFc HyperXCmd.h æT #define æD #define xreqReturnToPas 27 æC æKY xreqScanToReturn æFc HyperXCmd.h æT #define æD #define xreqScanToReturn 28 æC æKY xreqScanToZero æFc HyperXCmd.h æT #define æD #define xreqScanToZero 39 /* Yes, really 39!*/ æC æKY XCmdBlock XCmdPtr æFc HyperXCmd.h æT struct æD struct XCmdBlock { short paramCount; Handle params[16]; Handle returnValue; Boolean passFlag; void (*entryPoint)(); /*to call back to HyperCard*/ short request; short result; long inArgs[8]; long outArgs[4]; }; typedef struct XCmdBlock XCmdBlock; typedef XCmdBlock *XCmdPtr; æC æKY SendCardMessage æFc HyperXCmd.h æT Function æD pascal void SendCardMessage(XCmdPtr paramPtr,const Str255 msg); æDT SendCardMessage((XCmdPtr) paramPtr,(const Str255) msg); æC æKY SendHCMessage æFc HyperXCmd.h æT Function æD pascal void SendHCMessage(XCmdPtr paramPtr,const Str255 msg); æDT SendHCMessage((XCmdPtr) paramPtr,(const Str255) msg); æC æKY GetGlobal æFc HyperXCmd.h æT Function æD pascal Handle GetGlobal(XCmdPtr paramPtr,const Str255 globName); æDT Handle myVariable = GetGlobal((XCmdPtr) paramPtr,(const Str255) globName); æC æKY SetGlobal æFc HyperXCmd.h æT Function æD pascal void SetGlobal(XCmdPtr paramPtr,const Str255 globName,Handle globValue); æDT SetGlobal((XCmdPtr) paramPtr,(const Str255) globName,(Handle) globValue); æC æKY GetFieldByID æFc HyperXCmd.h æT Function æD pascal Handle GetFieldByID(XCmdPtr paramPtr,Boolean cardFieldFlag,short fieldID); æDT Handle myVariable = GetFieldByID((XCmdPtr) paramPtr,(Boolean) cardFieldFlag,(short) fieldID); æC æKY GetFieldByName æFc HyperXCmd.h æT Function æD pascal Handle GetFieldByName(XCmdPtr paramPtr,Boolean cardFieldFlag,const Str255 fieldName); æDT Handle myVariable = GetFieldByName((XCmdPtr) paramPtr,(Boolean) cardFieldFlag,(const Str255) fieldName); æC æKY GetFieldByNum æFc HyperXCmd.h æT Function æD pascal Handle GetFieldByNum(XCmdPtr paramPtr,Boolean cardFieldFlag,short fieldNum); æDT Handle myVariable = GetFieldByNum((XCmdPtr) paramPtr,(Boolean) cardFieldFlag,(short) fieldNum); æC æKY SetFieldByID æFc HyperXCmd.h æT Function æD pascal void SetFieldByID(XCmdPtr paramPtr,Boolean cardFieldFlag,short fieldID, Handle fieldVal); æDT SetFieldByID((XCmdPtr) paramPtr,(Boolean) cardFieldFlag,(short) fieldID,() Handle fieldVal); æC æKY SetFieldByName æFc HyperXCmd.h æT Function æD pascal void SetFieldByName(XCmdPtr paramPtr,Boolean cardFieldFlag,const Str255 fieldName, Handle fieldVal); æDT SetFieldByName((XCmdPtr) paramPtr,(Boolean) cardFieldFlag,(const Str255) fieldName,() Handle fieldVal); æC æKY SetFieldByNum æFc HyperXCmd.h æT Function æD pascal void SetFieldByNum(XCmdPtr paramPtr,Boolean cardFieldFlag,short fieldNum, Handle fieldVal); æDT SetFieldByNum((XCmdPtr) paramPtr,(Boolean) cardFieldFlag,(short) fieldNum,() Handle fieldVal); æC æKY BoolToStr æFc HyperXCmd.h æT Function æD pascal void BoolToStr(XCmdPtr paramPtr,Boolean bool,Str255 str); æDT BoolToStr((XCmdPtr) paramPtr,(Boolean) bool,(Str255) str); æC æKY ExtToStr æFc HyperXCmd.h æT Function æD pascal void ExtToStr(XCmdPtr paramPtr,extended *num,Str255 str); æDT ExtToStr((XCmdPtr) paramPtr,(extended *) num,(Str255) str); æC æKY LongToStr æFc HyperXCmd.h æT Function æD pascal void LongToStr(XCmdPtr paramPtr,long posNum,Str255 str); æDT LongToStr((XCmdPtr) paramPtr,(long) posNum,(Str255) str); æC æKY NumToStr æFc HyperXCmd.h æT Function æD pascal void NumToStr(XCmdPtr paramPtr,long num,Str255 str); æDT NumToStr((XCmdPtr) paramPtr,(long) num,(Str255) str); æC æKY NumToHex æFc HyperXCmd.h æT Function æD pascal void NumToHex(XCmdPtr paramPtr,long num,short nDigits,Str255 str); æDT NumToHex((XCmdPtr) paramPtr,(long) num,(short) nDigits,(Str255) str); æC æKY StrToBool æFc HyperXCmd.h æT Function æD pascal Boolean StrToBool(XCmdPtr paramPtr,const Str255 str); æDT Boolean myVariable = StrToBool((XCmdPtr) paramPtr,(const Str255) str); æC æKY StrToExt æFc HyperXCmd.h æT Function æD pascal extended StrToExt(XCmdPtr paramPtr,const Str255 str); æDT extended myVariable = StrToExt((XCmdPtr) paramPtr,(const Str255) str); æC æKY StrToLong æFc HyperXCmd.h æT Function æD pascal long StrToLong(XCmdPtr paramPtr,const Str255 str); æDT long myVariable = StrToLong((XCmdPtr) paramPtr,(const Str255) str); æC æKY StrToNum æFc HyperXCmd.h æT Function æD pascal long StrToNum(XCmdPtr paramPtr,const Str255 str); æDT long myVariable = StrToNum((XCmdPtr) paramPtr,(const Str255) str); æC æKY PasToZero æFc HyperXCmd.h æT Function æD pascal Handle PasToZero(XCmdPtr paramPtr,const Str255 str); æDT Handle myVariable = PasToZero((XCmdPtr) paramPtr,(const Str255) str); æC æKY ZeroToPas æFc HyperXCmd.h æT Function æD pascal void ZeroToPas(XCmdPtr paramPtr,char *zeroStr,Str255 pasStr); æDT ZeroToPas((XCmdPtr) paramPtr,(char *) zeroStr,(Str255) pasStr); æC æKY EvalExpr æFc HyperXCmd.h æT Function æD pascal Handle EvalExpr(XCmdPtr paramPtr,const Str255 expr); æDT Handle myVariable = EvalExpr((XCmdPtr) paramPtr,(const Str255) expr); æC æKY ReturnToPas æFc HyperXCmd.h æT Function æD pascal void ReturnToPas(XCmdPtr paramPtr,Ptr zeroStr,Str255 pasStr); æDT ReturnToPas((XCmdPtr) paramPtr,(Ptr) zeroStr,(Str255) pasStr); æC æKY ScanToReturn æFc HyperXCmd.h æT Function æD pascal void ScanToReturn(XCmdPtr paramPtr,Ptr *scanPtr); æDT ScanToReturn((XCmdPtr) paramPtr,(Ptr *) scanPtr); æC æKY ScanToZero æFc HyperXCmd.h æT Function æD pascal void ScanToZero(XCmdPtr paramPtr,Ptr *scanPtr); æDT ScanToZero((XCmdPtr) paramPtr,(Ptr *) scanPtr); æC æKY StringEqual æFc HyperXCmd.h æT Function æD pascal Boolean StringEqual(XCmdPtr paramPtr,const Str255 str1,const Str255 str2); æDT Boolean myVariable = StringEqual((XCmdPtr) paramPtr,(const Str255) str1,(const Str255) str2); æC æKY StringMatch æFc HyperXCmd.h æT Function æD pascal Ptr StringMatch(XCmdPtr paramPtr,const Str255 pattern,Ptr target); æDT Ptr myVariable = StringMatch((XCmdPtr) paramPtr,(const Str255) pattern,(Ptr) target); æC æKY StringLength æFc HyperXCmd.h æT Function æD pascal long StringLength(XCmdPtr paramPtr,char *strPtr); æDT long myVariable = StringLength((XCmdPtr) paramPtr,(char *) strPtr); æC æKY ZeroBytes æFc HyperXCmd.h æT Function æD pascal void ZeroBytes(XCmdPtr paramPtr,Ptr dstPtr,long longCount); æDT ZeroBytes((XCmdPtr) paramPtr,(Ptr) dstPtr,(long) longCount); æC æKY IOCtl.h ioctl æFc IOCtl.h æC ioctl FIOBUFSIZE FIOINTERACTIVE FIOSETEOF TIOSPORT FIODUPFD FIOLSEEK TIOFLUSH FIOFNAME FIOREFNUM TIOGPORT Synopsis #include <IOCtl.h> int ioctl(int fildes, unsigned int cmd, long *arg); Description The ioctl; function communicates with a file’s device driver by sending control information, requesting status information, or both. Parameter cmd indicates which device-specific operations ioctl must perform. Here are the control values. Value of cmd Description FIOINTERACTIVE The ioctl function returns 0 if the device is interactive; if not, it returns –1 and errno is set to EINVAL. Parameter arg is ignored. FIOBUFSIZE The ioctl function returns, in bytes, the optimal buffer size for this device; the buffer size is returned in a long pointed to by arg. If the device has no default buffer size, ioctl returns –1 and errno is set to EINVAL. FIOFNAME The ioctl function stores the filename associated with fildes in a C string pointed to by arg. It returns –1 if the filename exceeds 255 characters [E2BIG]. Use only for a program running as an MPW tool. FIOREFNUM The ioctl function returns the Macintosh file reference number associated with fildes; the reference number is returned in the short pointed to by arg. If the fildes is not open on a Macintosh file (such as the console device), ioctl returns –1. FIOSETEOF The ioctl function sets the logical end-of-file specified in the long parameter arg. The value of arg is the new size of the file, in bytes. This command can be used to reduce or increase the size of the open file. The current file pointer is not affected unless the file size is set below it. TIOFLUSH Used only for the console device and other terminal devices. The ioctlfunction returns –1 if fildes is not a terminal device. TIOFLUSH tells the device driver to throw away unread terminal input. Parameter arg is ignored. Diagnostics If an error has occurred, a value of –1 is returned and errno is set to indicate the error. Note For cmd values FIOINTERACTIVE and FIOBUFSIZE, a function return of –1 is a meaningful response, not an error. For FIOINTERACTIVE, errno is set to EINVAL for devices that are not interactive. For FIOBUFSIZE, errno is set to EINVAL for devices that have no default buffering. The cmd values FIOLSEEK and FIODUPFD are reserved for operating-system use. If you set the console GrafPort with TIOSPORT, do not deallocate the storage for that port; the console device is written to by the exit function as your application terminates. The console device ioctl control values TIOGPORT and TIOSPORT are no longer supported. It is no longer possible to perform direct I/O to a user-supplied GrafPort. Warning FIOREFNUM lets you do Macintosh I/O operations, such as Allocate, that are not available through ioctl. Do not close or modify the file pointer by using the reference number. See also fcntl, faccess, ferror æKY FIOBUFSIZE æFc IOCtl.h æD #define FIOBUFSIZE (('f'<<8)|03) /*Return optimal buffer size*/ æKY FIODUPFD æFc IOCtl.h æD #define FIODUPFD (('f'<<8)|01) /*3rd arg is min new fd number*/ æKY FIOFNAME æFc IOCtl.h æD #define FIOFNAME (('f'<<8)|04) /*Return filename*/ æKY FIOINTERACTIVE æFc IOCtl.h æD #define FIOINTERACTIVE (('f'<<8)|02) /*If device is interactive*/ æKY FIOLSEEK æFc IOCtl.h æD #define FIOLSEEK (('f'<<8)|00) /*3rd arg is a _SeekType (below)*/ æKY FIOREFNUM æFc IOCtl.h æD #define FIOREFNUM (('f'<<8)|05) /*Return fs refnum*/ æKY FIOSETEOF æFc IOCtl.h æD #define FIOSETEOF (('f'<<8)|06) /*Set file length*/ æKY TIOFLUSH æFc IOCtl.h æD #define TIOFLUSH (('t'<<8)|00) æKY TIOGPORT æFc IOCtl.h æD #define TIOGPORT (('t'<<8)|02) æKY TIOSPORT æFc IOCtl.h æD #define TIOSPORT (('t'<<8)|01) æKY ioctlæ æDT int myVariable = ioctl((int) fildes, (unsigned int) cmd, (long *)arg); æKY Limits.h æFc Limits.h æD Synopsis #define CHAR_BIT 8 #define MB_LEN_MAX 2 #define CHAR_MI (-128) #define CHAR_MAX 127 #define SCHAR_MI (-128) #define SCHAR_MAX 127 #define UCHAR_MAX 255U #define SHRT_MI (-32768) #define SHRT_MAX 32767 #define USHRT_MAX 65535U #define INT_MI (-2147483648) #define INT_MAX 2147483647 #define UINT_MAX 4294967295U #define LONG_MI (-2147483648) #define LONG_MAX 2147483647 #define ULONG_MAX 4294967295U æC Description The header <Limits.h> specifies the number of bits in a byte, and the minimum and maximum values for the integral types (that is, char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, and unsigned l